contracts

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: May 25, 2026 License: GPL-3.0 Imports: 4 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EventClusterNodeJoined    = "cluster.node.joined"
	EventClusterNodeLeft      = "cluster.node.left"
	EventClusterNodeDegraded  = "cluster.node.degraded"
	EventClusterLeaderChanged = "cluster.leader.changed"
)

Cluster event types for the event bus.

View Source
const (
	EventMediaRequested     = "media.requested"
	EventDownloadStarted    = "download.started"
	EventDownloadCompleted  = "download.completed"
	EventDownloadFailed     = "download.failed"
	EventTranscodeStarted   = "transcode.started"
	EventTranscodeCompleted = "transcode.completed"
	EventTranscodeFailed    = "transcode.failed"
	EventLibraryItemAdded   = "library.item.added"
	EventLibraryItemRemoved = "library.item.removed"
	EventContentMissing     = "content.missing"
	EventContentFetched     = "content.fetched"
	EventPlaybackStarted    = "playback.started"
	EventPlaybackStopped    = "playback.stopped"
	EventModuleRegistered   = "module.registered"
	EventModuleUnregistered = "module.unregistered"
	EventModuleDegraded     = "module.degraded"
	EventQualityDecision    = "quality.decision"
	EventFormatMatched      = "format.matched"
	EventMediaAnalyzed      = "media.analyzed"
)

Well-known event types

View Source
const EventSchemaVersion = "v1"

EventSchemaVersion is the current schema version for all event payloads. When a breaking change is made, this is incremented.

View Source
const EventStorageTierTransition = "storage.tier.transition"

EventStorageTierTransition is emitted when an object moves between tiers.

Variables

This section is empty.

Functions

func Register

func Register(factory ModuleFactory)

Register is called by module init() functions to make a module available for auto-loading. Modules that call this are loaded when LoadRegistered is called during bootstrap.

Types

type AssetRef

type AssetRef struct {
	ID       string
	Storage  string
	MIMEType string
	Size     int64
	Quality  string
}

type AtomicMovable

type AtomicMovable interface {
	AtomicMove(ctx context.Context, src, dst string) error
}

type AuditEntry

type AuditEntry struct {
	ID         string
	Timestamp  time.Time
	Actor      string            // user ID, "system", or module ID
	Action     string            // e.g., "http.request", "module.registered", "media.requested"
	Resource   string            // e.g., "/api/movies", "admin-ui", "Inception"
	ResourceID string            // UUID of the affected resource, if applicable
	Details    map[string]string // arbitrary context
	TraceID    string
	NodeID     string
}

AuditEntry is a single audit log record.

type AuditFilter

type AuditFilter struct {
	Actor    string
	Action   string
	Resource string
	From     time.Time
	To       time.Time
	TraceID  string
}

AuditFilter narrows audit queries.

type AuditLogger

type AuditLogger interface {
	// Log records an audit entry.
	Log(ctx context.Context, entry AuditEntry) error

	// Query returns entries matching the filter.
	Query(ctx context.Context, filter AuditFilter) ([]AuditEntry, error)

	// Export writes all entries in the given format (json, csv).
	Export(ctx context.Context, format string) (io.Reader, error)
}

AuditLogger records and queries audit entries.

type AuthProvider

type AuthProvider interface {
	Authenticate(ctx context.Context, credentials any) (Session, error)
	Validate(ctx context.Context, token string) (Session, error)
	Revoke(ctx context.Context, token string) error
}

type Authorizer

type Authorizer interface {
	Can(ctx context.Context, session Session, action string, resource string) (bool, error)
}

type BackupInfo

type BackupInfo struct {
	ID        string
	Timestamp int64
	Size      int64
	Modules   []string // module IDs included in the backup
}

BackupInfo describes a completed backup.

type BackupProvider

type BackupProvider interface {
	// CreateBackup captures state from all registered Backupable modules.
	CreateBackup(ctx context.Context) (BackupInfo, error)
	// Restore restores state from a previous backup.
	Restore(ctx context.Context, backupID string) error
	// ListBackups returns all available backups.
	ListBackups(ctx context.Context) ([]BackupInfo, error)
	// DeleteBackup removes a stored backup.
	DeleteBackup(ctx context.Context, backupID string) error
}

BackupProvider is implemented by backup modules (backup-local, backup-s3, etc.)

type Backupable

type Backupable interface {
	// ExportState returns serialized state for backup.
	ExportState(ctx context.Context) ([]byte, error)
	// ImportState restores state from a backup.
	ImportState(ctx context.Context, data []byte) error
}

Backupable is implemented by modules that have state to back up.

type CacheLayer added in v0.1.1

type CacheLayer interface {
	// Get returns cached data for the given key. The bool indicates a cache hit.
	Get(ctx context.Context, key string) ([]byte, bool)
	// Set caches data for the given key.
	Set(ctx context.Context, key string, data []byte) error
	// Invalidate removes all cached entries whose key has the given prefix.
	Invalidate(ctx context.Context, prefix string) error
}

CacheLayer is an optional read-through cache for the storage orchestrator. Unlike CacheProvider (distributed caches for application state), CacheLayer provides local caching for storage objects. Implemented by cache-memory and similar modules. Core discovers a CacheLayer at bootstrap; if none is found, the orchestrator operates without a cache.

type CacheProvider

type CacheProvider interface {
	// Get retrieves a value by key. Returns nil, nil if the key does not exist.
	Get(ctx context.Context, key string) ([]byte, error)
	// Set stores a value with an optional TTL. Zero TTL means no expiration.
	Set(ctx context.Context, key string, value []byte, ttl time.Duration) error
	// Delete removes one or more keys.
	Delete(ctx context.Context, keys ...string) error
	// Exists checks whether a key exists.
	Exists(ctx context.Context, key string) (bool, error)
	// Incr atomically increments an integer key by delta and returns the new value.
	Incr(ctx context.Context, key string, delta int64) (int64, error)
	// Lock acquires a distributed lock on a key. Returns a Lock handle.
	// If the key is already locked, returns an error immediately (non-blocking).
	Lock(ctx context.Context, key string, ttl time.Duration) (LockHandle, error)
	// Publish sends a message on a pub/sub channel.
	Publish(ctx context.Context, channel string, msg []byte) error
	// Subscribe returns a channel that receives messages published on the given channel.
	Subscribe(ctx context.Context, channel string) (<-chan []byte, error)
}

CacheProvider is implemented by cache modules (cache-redis, cache-valkey, etc.) to provide ephemeral state, distributed locks, and pub/sub. Core defines the contract; modules provide the driver.

type Cluster

type Cluster interface {
	// Start joins or forms a cluster. If no seed nodes are reachable,
	// the node starts a new single-node cluster.
	Start(ctx context.Context) error

	// Stop gracefully leaves the cluster.
	Stop(ctx context.Context) error

	// Members returns all current cluster members.
	Members() []NodeInfo

	// Leader returns the current leader, or nil if unknown.
	Leader() *NodeInfo

	// LocalNode returns information about this node.
	LocalNode() NodeInfo

	// Events returns a channel that emits cluster membership changes.
	Events() <-chan ClusterEvent

	// Health checks whether the cluster is operational.
	Health(ctx context.Context) error
}

Cluster manages node membership, leader election, and peer discovery.

type ClusterEvent

type ClusterEvent struct {
	Type     ClusterEventType
	Node     NodeInfo
	LeaderID string
}

ClusterEvent is emitted when cluster membership changes.

type ClusterEventType

type ClusterEventType string

ClusterEventType describes the kind of membership change.

const (
	ClusterNodeJoined    ClusterEventType = "node.joined"
	ClusterNodeLeft      ClusterEventType = "node.left"
	ClusterNodeDegraded  ClusterEventType = "node.degraded"
	ClusterLeaderChanged ClusterEventType = "leader.changed"
)

type ContentCandidate

type ContentCandidate struct {
	ID          string // provider-specific identifier
	Kind        string // "subtitle", "lyrics", "chapters", etc.
	Language    string
	Title       string // human-readable label
	Format      string // "srt", "lrc", "txt", etc.
	ProviderID  string // which provider returned this
	DownloadURL string
	Score       int // relevance, higher is better
}

ContentCandidate is a single result from a supplementary content search.

type ContentFetchedPayload

type ContentFetchedPayload struct {
	MediaID  string `json:"media_id"`
	Kind     string `json:"kind"`
	Language string `json:"language"`
	Provider string `json:"provider"`
	Format   string `json:"format,omitempty"`
}

ContentFetchedPayload is the payload for content.fetched events. Emitted when supplementary content has been fetched for a media object.

type ContentMissingPayload

type ContentMissingPayload struct {
	MediaID  string `json:"media_id"`
	Kind     string `json:"kind"` // "subtitle", "lyrics", "chapters", etc.
	Language string `json:"language"`
}

ContentMissingPayload is the payload for content.missing events. Emitted when supplementary content (subtitles, lyrics, chapters, etc.) is needed for a media object. The Kind field identifies the type of content needed.

type ContentResult

type ContentResult struct {
	MediaID  string
	Kind     string
	Language string
	Format   string
	// Data is the content itself. For companion files (.srt, .lrc), this is the raw
	// file contents. For metadata enrichment, this is serialized field data.
	Data []byte
	// EmbedInMetadata is true when Data should be merged into the media object's
	// Fields map rather than stored as a companion file.
	EmbedInMetadata bool
}

ContentResult is the fetched supplementary content.

type CustomFormat

type CustomFormat struct {
	ID          string
	Name        string
	Description string
	// Tags that get applied to releases matching this format.
	Tags []string
	// Score modifier applied when this format matches (+100 = prefer, -100 = avoid).
	Score int
}

CustomFormat defines a user-created rule for tagging or scoring releases.

type DatabaseProvider

type DatabaseProvider interface {
	// Open initializes the database connection.
	Open(ctx context.Context, connString string) error
	// Close gracefully shuts down the database connection.
	Close(ctx context.Context) error
	// Health checks whether the database is reachable.
	Health(ctx context.Context) error
	// Exec runs a statement that modifies data (INSERT, UPDATE, DELETE, DDL).
	Exec(ctx context.Context, query string, args ...any) (int64, error)
	// Query runs a read query and returns a row iterator.
	Query(ctx context.Context, query string, args ...any) (Rows, error)
	// Transaction runs fn inside a database transaction, committing on success and rolling back on error.
	Transaction(ctx context.Context, fn func(Tx) error) error
	// Migrate applies ordered schema migrations. Implementations track which migrations
	// have already been applied and skip those.
	Migrate(ctx context.Context, migrations []Migration) error
}

DatabaseProvider is implemented by database modules (database-postgres, database-sqlite, etc.) to provide persistent storage for modules. Core defines the contract; modules provide the driver.

type DownloadCompletedPayload

type DownloadCompletedPayload struct {
	RequestID  string `json:"request_id"`
	DownloadID string `json:"download_id"`
	Title      string `json:"title"`
}

DownloadCompletedPayload is the payload for download.completed events.

type DownloadFailedPayload

type DownloadFailedPayload struct {
	DownloadID string `json:"download_id"`
	Title      string `json:"title"`
	Error      string `json:"error"`
}

DownloadFailedPayload is the payload for download.failed events.

type DownloadFileInfo

type DownloadFileInfo struct {
	Name string
	Size int64
	Path string
}

type DownloadInfo

type DownloadInfo struct {
	ID         string
	Name       string
	Status     DownloadStatus
	Progress   float64
	SizeBytes  int64
	Downloaded int64
	Uploaded   int64
	SpeedDown  int64
	SpeedUp    int64
	ETA        int64
	Seeders    int
	Leechers   int
	Files      []DownloadFileInfo
}

type DownloadStartedPayload

type DownloadStartedPayload struct {
	DownloadID string `json:"download_id"`
	Title      string `json:"title"`
	Size       int64  `json:"size,omitempty"`
}

DownloadStartedPayload is the payload for download.started events.

type DownloadStatus

type DownloadStatus string
const (
	DownloadQueued      DownloadStatus = "queued"
	DownloadDownloading DownloadStatus = "downloading"
	DownloadCompleted   DownloadStatus = "completed"
	DownloadFailed      DownloadStatus = "failed"
	DownloadPaused      DownloadStatus = "paused"
)

type DownloadTask

type DownloadTask struct {
	ID         string
	MagnetURI  string
	TorrentURL string
	NZBData    []byte
	DestPath   string
	Label      string
	Priority   int
}

type Downloader

type Downloader interface {
	Add(ctx context.Context, task DownloadTask) (string, error)
	Remove(ctx context.Context, id string, deleteData bool) error
	Pause(ctx context.Context, id string) error
	Resume(ctx context.Context, id string) error
	Status(ctx context.Context, id string) (DownloadInfo, error)
	List(ctx context.Context) ([]DownloadInfo, error)
}

type Event

type Event struct {
	ID        string
	Type      string
	Source    string
	TraceID   string
	Payload   []byte
	Metadata  map[string]string
	Timestamp time.Time
}

type EventBus

type EventBus interface {
	Publish(ctx context.Context, event Event) error
	Subscribe(ctx context.Context, eventType string, handler EventHandler) error
	Unsubscribe(ctx context.Context, eventType string, handler EventHandler) error
	Request(ctx context.Context, event Event, timeout time.Duration) (Event, error)
}

type EventHandler

type EventHandler func(ctx context.Context, event Event) error

type Executor

type Executor interface {
	// CanHandle returns true if this executor accepts the given task type.
	CanHandle(taskType string) bool

	// Execute runs the task and returns the result payload on success,
	// or an error on failure.
	Execute(ctx context.Context, task WorkerTask) (result []byte, err error)
}

Executor is implemented by modules that can run tasks of a given type. When a WorkerPool assigns a task to a node, it finds an Executor on that node that declares the task type in its capabilities.

type FileEvent

type FileEvent struct {
	Path    string
	OldPath string // populated for rename events
	Type    FileEventType
	Size    int64
	ModTime int64
}

FileEvent describes a filesystem change.

type FileEventType

type FileEventType string

FileEventType describes what happened to a file.

const (
	FileCreated  FileEventType = "created"
	FileModified FileEventType = "modified"
	FileDeleted  FileEventType = "deleted"
	FileRenamed  FileEventType = "renamed"
)

type FileWatcher

type FileWatcher interface {
	// Watch starts watching a directory for matching files. Returns a channel
	// that receives file events. Patterns are glob-style (e.g., "*.mkv", "*.mp4").
	Watch(ctx context.Context, path string, patterns []string) (<-chan FileEvent, error)
	// Unwatch stops watching a directory.
	Unwatch(ctx context.Context, path string) error
}

FileWatcher watches directories for filesystem changes and emits events. Core provides the event stream; modules subscribe to react (e.g., media-library auto-imports new files, transcoders detect new media to process).

type FormatCondition

type FormatCondition struct {
	Field    string // field to check: "title", "codec", "audio", "source", "size"
	Operator string // "contains", "equals", "regex", "gte", "lte"
	Value    string // value to match against
}

FormatCondition is a single condition within a custom format.

type FormatMatchedPayload

type FormatMatchedPayload struct {
	ReleaseTitle string `json:"release_title"`
	Format       string `json:"format"`
	Score        int    `json:"score"`
}

FormatMatchedPayload is the payload for format.matched events.

type FormatMatcher

type FormatMatcher interface {
	// Match evaluates a candidate against conditions and returns the format if matched.
	Match(ctx context.Context, format CustomFormat, candidate ReleaseCandidate) (bool, error)
}

FormatMatcher evaluates whether a release matches a custom format.

type Hardlinkable

type Hardlinkable interface {
	Hardlink(ctx context.Context, src, dst string) error
}

type HealthMonitor added in v0.1.1

type HealthMonitor interface {
	// StartMonitoring begins periodic health checking. The monitor calls Health()
	// on every registered module at the configured interval and publishes
	// events on the bus for any degraded modules.
	StartMonitoring(ctx context.Context, reg ServiceRegistry, bus EventBus) error

	// Stop gracefully stops the health monitor.
	Stop(ctx context.Context) error
}

HealthMonitor runs periodic health checks on all registered modules and publishes module.degraded events for unhealthy modules. Core starts the HealthMonitor at bootstrap if one is discovered from the registry. If no module implements this contract, periodic health monitoring is skipped (modules still report via /health endpoint).

type ImportListInfo

type ImportListInfo struct {
	ID          string
	Name        string
	Description string
	MediaType   string // primary media type this list provides
	URL         string // source URL if applicable
}

ImportListInfo describes an import list source.

type ImportListItem

type ImportListItem struct {
	Title      string
	MediaType  string // "movie", "tv", "music", etc.
	ExternalID string // ID from the source service (e.g. Trakt ID, IMDb ID)
	Year       int
	Source     string // "trakt", "plex", "myanimelist", "rss", etc.
	Status     string // "wanted", "collected", "watched"
	Metadata   map[string]string
}

ImportListItem is a single item from an external watchlist or import source.

type ImportListProvider

type ImportListProvider interface {
	// FetchItems retrieves items from the external source.
	FetchItems(ctx context.Context) ([]ImportListItem, error)
	// ListInfo returns metadata about this import list.
	ListInfo(ctx context.Context) ImportListInfo
}

ImportListProvider is implemented by import list modules (importlist-trakt, etc.)

type Indexer

type Indexer interface {
	Name() string
	Search(ctx context.Context, query SearchQuery) ([]IndexerResult, error)
	Capabilities(ctx context.Context) ([]string, error)
}

type IndexerResult

type IndexerResult struct {
	Title       string
	GUID        string
	Link        string
	MagnetURI   string
	Size        int64
	Seeders     int
	Leechers    int
	PublishDate string
	Categories  []string
	Source      string
	Extra       map[string]string // unknown Torznab/Newznab attributes preserved here
}

type LeaderChangedPayload

type LeaderChangedPayload struct {
	PreviousLeader string `json:"previous_leader"`
	NewLeader      string `json:"new_leader"`
}

LeaderChangedPayload is the payload for cluster.leader.changed events.

type LibraryItemAddedPayload

type LibraryItemAddedPayload struct {
	ID    string `json:"id"`
	Title string `json:"title"`
	Type  string `json:"type"`
}

LibraryItemAddedPayload is the payload for library.item.added events.

type LibraryItemRemovedPayload

type LibraryItemRemovedPayload struct {
	ID    string `json:"id"`
	Title string `json:"title"`
}

LibraryItemRemovedPayload is the payload for library.item.removed events.

type LockHandle

type LockHandle interface {
	// Unlock releases the lock.
	Unlock(ctx context.Context) error
}

LockHandle represents an acquired distributed lock.

type MediaAnalyzedPayload

type MediaAnalyzedPayload struct {
	Path       string  `json:"path"`
	Codec      string  `json:"codec"`
	Resolution string  `json:"resolution"`
	Duration   float64 `json:"duration"`
}

MediaAnalyzedPayload is the payload for media.analyzed events.

type MediaFieldSchema

type MediaFieldSchema struct {
	Key         string
	Type        MediaFieldType
	Description string
}

MediaFieldSchema describes one field in a media type's metadata schema.

type MediaFieldType

type MediaFieldType string

MediaFieldType enumerates the types supported in media type schemas.

const (
	FieldTypeString      MediaFieldType = "string"
	FieldTypeInt         MediaFieldType = "int"
	FieldTypeFloat       MediaFieldType = "float"
	FieldTypeBool        MediaFieldType = "bool"
	FieldTypeStringSlice MediaFieldType = "string_slice"
)

type MediaInfo

type MediaInfo struct {
	Path     string
	Duration float64 // seconds
	Bitrate  int64   // overall bitrate in bps
	Size     int64   // file size in bytes

	// Video streams
	VideoCodec  string // e.g., "h264", "hevc", "av1", "vp9"
	Resolution  string // e.g., "1920x1080"
	Width       int
	Height      int
	AspectRatio string // e.g., "16:9"
	FrameRate   float64
	BitDepth    int    // 8, 10, 12
	HDR         string // "HDR10", "HDR10+", "DolbyVision", "" if SDR
	ColorSpace  string

	// Audio streams
	AudioCodecs    []string // e.g., ["aac", "ac3", "dts"]
	AudioChannels  []string // e.g., ["5.1", "2.0", "7.1"]
	AudioLanguages []string // e.g., ["eng", "jpn"]
	Atmos          bool

	// Subtitles
	SubtitleLanguages []string // e.g., ["eng", "fre"]
	SubtitleFormats   []string // e.g., ["srt", "pgs", "ass"]
	ForcedSubtitles   []string // languages with forced subs

	// Container
	Container string // e.g., "mkv", "mp4", "avi"

	// Chapters
	Chapters int
}

MediaInfo holds codec and technical metadata about a media file.

type MediaInfoProvider

type MediaInfoProvider interface {
	// Analyze inspects a media file and returns its technical metadata.
	Analyze(ctx context.Context, path string) (MediaInfo, error)

	// Probe quickly checks if a file contains valid media (fast path, no deep analysis).
	Probe(ctx context.Context, path string) (MediaInfo, error)
}

MediaInfoProvider analyzes media files and returns technical metadata. Modules implement this to provide codec/format analysis (ffprobe, MediaInfo, etc.).

type MediaLibrary

type MediaLibrary interface {
	Add(ctx context.Context, obj MediaObject) error
	Remove(ctx context.Context, id string) error
	Get(ctx context.Context, id string) (MediaObject, error)
	List(ctx context.Context, mediaType MediaType, offset, limit int) ([]MediaObject, error)
	Search(ctx context.Context, query string) ([]MediaObject, error)
}

type MediaObject

type MediaObject struct {
	ID     string
	Type   MediaType
	Title  string
	Assets []AssetRef
	Fields map[string]any
}

MediaObject represents an item in the media library. Core fields (ID, Type, Title, Assets) are universal. Type-specific metadata lives in Fields, validated against the MediaTypeSchema registered by the module that owns the media type.

type MediaRequestedPayload

type MediaRequestedPayload struct {
	MediaType string `json:"media_type"`
	Title     string `json:"title"`
	Year      int    `json:"year,omitempty"`
	TmdbID    string `json:"tmdb_id,omitempty"`
	Quality   string `json:"quality,omitempty"`
}

MediaRequestedPayload is the payload for media.requested events.

type MediaType

type MediaType string

MediaType is a user-defined string that names a media type (e.g. "movie", "comic-book", "4k-movie"). The constants below are common examples, not an exhaustive list — any string can be a media type. Each media type is associated with a module that handles its behavior. Multiple instances of the same type can coexist with different modules or configurations (e.g. "movie-720p", "movie-1080p", "movie-4k" all backed by the same or different movie modules).

const (
	MediaTypeMovie     MediaType = "movie"
	MediaTypeTV        MediaType = "tv"
	MediaTypeMusic     MediaType = "music"
	MediaTypeBook      MediaType = "book"
	MediaTypeAudiobook MediaType = "audiobook"
	MediaTypeManga     MediaType = "manga"
	MediaTypeAnime     MediaType = "anime"
	MediaTypePodcast   MediaType = "podcast"
)

type MediaTypeSchema

type MediaTypeSchema struct {
	MediaType MediaType
	Fields    []MediaFieldSchema
	ModuleID  string
}

MediaTypeSchema is the complete metadata schema for a single media type. Modules that own a media type register one of these at Init time.

type MediaTypeSchemaProvider

type MediaTypeSchemaProvider interface {
	MediaTypeSchema() MediaTypeSchema
}

MediaTypeSchemaProvider is an optional interface for modules that own a media type. Core discovers schemas at Init time via type assertion.

type Migration

type Migration struct {
	Version int
	Name    string
	Up      string // SQL to apply
	Down    string // SQL to roll back
}

Migration represents a versioned schema migration.

type Module

type Module interface {
	Info() ModuleInfo
	Init(ctx context.Context) error
	Start(ctx context.Context) error
	Stop(ctx context.Context) error
	Health(ctx context.Context) error
}

func LoadRegistered

func LoadRegistered(deps ModuleDeps) []Module

LoadRegistered creates all registered modules using the provided dependencies.

type ModuleDegradedPayload

type ModuleDegradedPayload struct {
	ModuleID string `json:"module_id"`
	Error    string `json:"error"`
}

ModuleDegradedPayload is the payload for module.degraded events.

type ModuleDeps

type ModuleDeps struct {
	Registry   ServiceRegistry
	EventBus   EventBus
	Routes     RouteRegistrar
	Cluster    Cluster
	Storage    StorageOrchestrator
	WorkerPool WorkerPool
	Audit      AuditLogger
}

ModuleDeps provides modules with the core services they need during construction.

type ModuleEntry

type ModuleEntry struct {
	Info   ModuleInfo
	State  ModuleState
	Module Module
}

ModuleEntry is a handle to a registered module, providing its info and the underlying Module instance for interface type assertion.

type ModuleFactory

type ModuleFactory func(deps ModuleDeps) Module

ModuleFactory is a constructor for a module. Modules call module.Register in their init() to make themselves available for auto-loading.

type ModuleInfo

type ModuleInfo struct {
	ID           string
	Name         string
	Version      string
	Kinds        []ModuleKind
	Description  string
	Author       string
	Capabilities []string
}

func (ModuleInfo) PrimaryKind

func (m ModuleInfo) PrimaryKind() string

PrimaryKind returns the first kind for display purposes. Modules with multiple kinds show their primary (first) kind in UIs.

type ModuleKind

type ModuleKind string
const (
	ModuleKindAuth         ModuleKind = "auth"
	ModuleKindProvider     ModuleKind = "provider"
	ModuleKindDownloader   ModuleKind = "downloader"
	ModuleKindIndexer      ModuleKind = "indexer"
	ModuleKindMediaManager ModuleKind = "media_manager"
	ModuleKindProcessor    ModuleKind = "processor"
	ModuleKindPlayback     ModuleKind = "playback"
	ModuleKindWorkflow     ModuleKind = "workflow"
	ModuleKindStorage      ModuleKind = "storage"
	ModuleKindUI           ModuleKind = "ui"
	ModuleKindAPI          ModuleKind = "api"
	ModuleKindEventBus     ModuleKind = "eventbus"
	ModuleKindScheduler    ModuleKind = "scheduler"
)

type ModuleRegisteredPayload

type ModuleRegisteredPayload struct {
	ModuleID string `json:"module_id"`
	Version  string `json:"version"`
}

ModuleRegisteredPayload is the payload for module.registered events.

type ModuleState

type ModuleState string
const (
	ModuleStateRegistered ModuleState = "registered"
	ModuleStateStarting   ModuleState = "starting"
	ModuleStateRunning    ModuleState = "running"
	ModuleStateDegraded   ModuleState = "degraded"
	ModuleStateStopping   ModuleState = "stopping"
	ModuleStateStopped    ModuleState = "stopped"
)

type ModuleUnregisteredPayload

type ModuleUnregisteredPayload struct {
	ModuleID string `json:"module_id"`
}

ModuleUnregisteredPayload is the payload for module.unregistered events.

type NodeInfo

type NodeInfo struct {
	ID        string
	GRPCAddr  string
	HTTPAddr  string
	Labels    map[string]string
	ModuleIDs []string
}

NodeInfo describes a node in the cluster.

type NodeJoinedPayload

type NodeJoinedPayload struct {
	NodeID   string `json:"node_id"`
	GRPCAddr string `json:"grpc_addr"`
	HTTPAddr string `json:"http_addr"`
}

NodeJoinedPayload is the payload for cluster.node.joined events.

type NodeLeftPayload

type NodeLeftPayload struct {
	NodeID string `json:"node_id"`
}

NodeLeftPayload is the payload for cluster.node.left events.

type Notification

type Notification struct {
	Title     string
	Body      string
	Level     NotificationLevel
	EventType string // the event that triggered this notification, e.g. "download.completed"
	MediaRef  string // optional media ID reference
	Channel   string // target channel: "discord", "telegram", "email", etc.
	Metadata  map[string]string
}

Notification is a message to be delivered to one or more channels.

type NotificationLevel

type NotificationLevel string

NotificationLevel indicates severity.

const (
	NotifyInfo  NotificationLevel = "info"
	NotifyWarn  NotificationLevel = "warn"
	NotifyError NotificationLevel = "error"
)

type NotificationProvider

type NotificationProvider interface {
	// Send delivers a notification.
	Send(ctx context.Context, n Notification) error
	// SupportedChannels returns the channel identifiers this provider handles.
	SupportedChannels() []string
	// Validate checks connectivity and configuration.
	Validate(ctx context.Context) error
}

NotificationProvider is implemented by notification modules (notifier-discord, notifier-telegram, etc.) Multiple notification modules can coexist. A notification router (core or module) dispatches each notification to the appropriate provider(s) based on per-event-type routing rules.

type ObjectInfo

type ObjectInfo struct {
	Key          string
	Size         int64
	ContentType  string
	ETag         string
	LastModified int64
	Metadata     map[string]string
}

type Playback

type Playback interface {
	// Ping checks if the media server is reachable.
	Ping(ctx context.Context) error

	// GetSessions returns all active playback sessions.
	GetSessions(ctx context.Context) ([]PlaybackSession, error)

	// RefreshLibrary triggers a library scan on the media server.
	RefreshLibrary(ctx context.Context) error

	// GetStreamURL returns a direct stream URL for the given item.
	GetStreamURL(ctx context.Context, itemID string) (string, error)
}

Playback is implemented by media server connectors (Jellyfin, Plex, Emby) to provide playback status and library sync capabilities.

type PlaybackSession

type PlaybackSession struct {
	ID        string
	UserID    string
	UserName  string
	ItemID    string
	ItemName  string
	MediaType string
	Position  int64 // ticks (1/10,000,000 of a second)
	Duration  int64 // ticks
	IsPaused  bool
	IsMuted   bool
	Volume    int
}

PlaybackSession represents an active playback session on a media server.

type PlaybackStartedPayload

type PlaybackStartedPayload struct {
	SessionID string `json:"session_id"`
	MediaID   string `json:"media_id"`
	Position  int64  `json:"position"`
}

PlaybackStartedPayload is the payload for playback.started events.

type PlaybackStoppedPayload

type PlaybackStoppedPayload struct {
	SessionID string `json:"session_id"`
	MediaID   string `json:"media_id"`
	Position  int64  `json:"position"`
}

PlaybackStoppedPayload is the payload for playback.stopped events.

type QualityDecision

type QualityDecision struct {
	Accepted bool
	Reason   string // why it was accepted or rejected
	Quality  string // detected quality of the release
	Upgrade  bool   // true if this release upgrades an existing one
	Score    int    // quality score for ranking (higher = better)
}

QualityDecision is the result of evaluating a release against a quality profile.

type QualityDecisionPayload

type QualityDecisionPayload struct {
	ReleaseTitle string `json:"release_title"`
	Profile      string `json:"profile"`
	Accepted     bool   `json:"accepted"`
	Reason       string `json:"reason"`
	Score        int    `json:"score"`
}

QualityDecisionPayload is the payload for quality.decision events.

type QualityProfile

type QualityProfile struct {
	ID         string
	Name       string
	MediaType  MediaType
	Upgradable bool     // if true, upgrade to better quality when available
	MinQuality string   // minimum acceptable quality (e.g., "HD-720p")
	MaxQuality string   // maximum desired quality (e.g., "4K-HDR")
	Preferred  []string // ordered list of preferred quality tags
	Cutoff     string   // stop searching once this quality is met
}

QualityProfile defines acceptable quality ranges for a media type.

type RateLimiterProvider added in v0.1.1

type RateLimiterProvider interface {
	// Allow checks whether a request from the given key (typically IP) is allowed.
	// Returns true if the request should proceed, false if it should be rate-limited.
	Allow(key string) bool

	// Enabled returns whether rate limiting is active.
	Enabled() bool
}

RateLimiterProvider is implemented by rate limiter modules (ratelimit-tokenbucket, etc.) to provide request rate limiting to the API server middleware chain. Core discovers a RateLimiterProvider at bootstrap and injects it into the middleware. If no module implements this contract, rate limiting is disabled (open mode).

type ReleaseCandidate

type ReleaseCandidate struct {
	Title    string
	Source   string // indexer name
	Size     int64
	Quality  string   // e.g., "1080p", "4K", "HDR"
	Codec    string   // e.g., "h264", "hevc", "av1"
	Audio    []string // audio formats present
	Seeders  int
	Leechers int
	Verified bool
	Repack   bool
	Proper   bool
	Scene    bool
}

ReleaseCandidate represents a found release being evaluated.

type ReleaseDecider

type ReleaseDecider interface {
	// Decide evaluates a candidate release against the given profile.
	Decide(ctx context.Context, profile QualityProfile, candidate ReleaseCandidate) (QualityDecision, error)
}

ReleaseDecider evaluates whether a candidate release matches a quality profile. Modules implement this to provide custom decision logic.

type ReleaseProfile

type ReleaseProfile struct {
	ID               string
	Name             string
	MediaType        MediaType
	QualityProfileID string
	Formats          []CustomFormat // custom formats with scores
	MinScore         int            // minimum score to accept
	PreferredTags    []string       // releases with these tags get bonus score
	MustNotContain   []string       // releases with these tags are rejected
}

ReleaseProfile combines quality profiles with custom formats for final scoring.

type RouteRegistrar

type RouteRegistrar interface {
	Handle(pattern string, handler http.Handler)
	HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request))
}

RouteRegistrar lets modules register HTTP handlers with the core API server.

type Rows

type Rows interface {
	Next() bool
	Scan(dest ...any) error
	Close() error
}

Rows is an iterator over query result rows.

type Scheduler

type Scheduler interface {
	Schedule(ctx context.Context, task Task) (string, error)
	Cancel(ctx context.Context, taskID string) error
	Status(ctx context.Context, taskID string) (TaskStatus, error)
}

type SearchQuery

type SearchQuery struct {
	Query      string
	Type       string // movie, tv, music, book, etc.
	Categories []string
	Season     int
	Episode    int
	Year       int
	Limit      int
}

type Seekable

type Seekable interface {
	Seek(ctx context.Context, key string, offset int64) (int64, error)
}

type ServiceRegistry

type ServiceRegistry interface {
	// FindByKind returns all registered modules of the given kind.
	FindByKind(kind ModuleKind) []ModuleEntry
	// FindByCapability returns all registered modules that declare the given capability.
	FindByCapability(cap string) []ModuleEntry
	// SupportsCapability checks whether a specific module supports the given capability.
	SupportsCapability(moduleID, cap string) bool
	// Resolve returns a single module by ID.
	Resolve(id string) (ModuleEntry, error)
	// ListAll returns every registered module.
	ListAll() []ModuleEntry

	// RegisterMediaSchema registers a metadata schema for a media type.
	// Returns an error if a schema for the same MediaType already exists.
	RegisterMediaSchema(schema MediaTypeSchema) error

	// MediaSchema returns the schema for a given media type, if registered.
	MediaSchema(mediaType MediaType) (MediaTypeSchema, bool)

	// MediaSchemas returns all registered media type schemas.
	MediaSchemas() []MediaTypeSchema
}

ServiceRegistry provides runtime discovery of registered modules. Modules receive this to find and communicate with other modules.

type Session

type Session struct {
	UserID      string
	Username    string
	Roles       []string
	Permissions []string
	Token       string
}

type SettingDef

type SettingDef struct {
	Key         string // env var or config key, e.g. "MUXCORE_JACKETT_URL"
	Label       string // human-readable label, e.g. "Jackett Server URL"
	Type        SettingType
	Default     string // default value as a string
	Description string // help text
	Required    bool
	Options     []string // for SettingTypeSelect: allowed values
	Group       string   // settings group, e.g. "Connection", "Downloads"
}

SettingDef describes one configuration setting that a module exposes.

type SettingType

type SettingType string

SettingType enumerates the supported setting types.

const (
	SettingTypeString SettingType = "string"
	SettingTypeInt    SettingType = "int"
	SettingTypeBool   SettingType = "bool"
	SettingTypeSelect SettingType = "select"
	SettingTypeSecret SettingType = "secret" // masked in UI, redacted in logs
)

type SettingsProvider

type SettingsProvider interface {
	Settings() []SettingDef
}

SettingsProvider is an optional interface modules implement to expose their configuration to the admin UI. The admin UI discovers all modules that implement this interface and renders their settings automatically.

type StepResult

type StepResult struct {
	Name   string
	Status string
	Output map[string]any
	Error  string
}

type StorageEvent

type StorageEvent struct {
	Type StorageEventType
	Key  string
}

type StorageEventType

type StorageEventType string
const (
	StorageEventCreated  StorageEventType = "created"
	StorageEventDeleted  StorageEventType = "deleted"
	StorageEventModified StorageEventType = "modified"
)

type StorageOrchestrator

type StorageOrchestrator interface {
	Get(ctx context.Context, key string) (io.ReadCloser, error)
	Put(ctx context.Context, key string, data io.Reader, size int64) error
	Delete(ctx context.Context, key string) error
	Move(ctx context.Context, src, dst string) error
	Exists(ctx context.Context, key string) (bool, error)
	Stat(ctx context.Context, key string) (ObjectInfo, error)
	List(ctx context.Context, prefix string) ([]ObjectInfo, error)
	ProviderCount() int
}

StorageOrchestrator is the high-level storage interface exposed to modules. It handles provider routing, caching, and capability negotiation internally.

type StorageProvider

type StorageProvider interface {
	Put(ctx context.Context, key string, data io.Reader, size int64) error
	Get(ctx context.Context, key string) (io.ReadCloser, error)
	Delete(ctx context.Context, key string) error
	Move(ctx context.Context, src, dst string) error
	Exists(ctx context.Context, key string) (bool, error)
	Stat(ctx context.Context, key string) (ObjectInfo, error)
	List(ctx context.Context, prefix string) ([]ObjectInfo, error)
}

Core blob storage interface — all storage providers implement this.

type StorageTier

type StorageTier string

Storage tier constants.

const (
	StorageTierHot     StorageTier = "hot"
	StorageTierWarm    StorageTier = "warm"
	StorageTierCold    StorageTier = "cold"
	StorageTierArchive StorageTier = "archive"
)

type Streamable

type Streamable interface {
	Stream(ctx context.Context, key string, offset, length int64) (io.ReadCloser, error)
}

type SupplementaryContentProvider

type SupplementaryContentProvider interface {
	// Search returns available content candidates for a media object.
	Search(ctx context.Context, media MediaObject, kind string, language string) ([]ContentCandidate, error)

	// Fetch retrieves content for a candidate. The result may embed metadata into the
	// media object or produce a companion file (e.g., .srt, .lrc).
	Fetch(ctx context.Context, candidate ContentCandidate) (*ContentResult, error)

	// SupportedKinds returns the content kinds this provider handles.
	SupportedKinds() []string
}

SupplementaryContentProvider finds and fetches supplementary content for media objects — subtitles, lyrics, chapter titles, alternate artwork, and any other content that enriches a media object, either as metadata fields or as companion files.

Kind strings ("subtitle", "lyrics", "chapters", etc.) are defined by modules, not core. Modules advertise their supported kinds via SupportedKinds() and are discoverable via ServiceRegistry.FindByCapability("content.subtitle").

type Tag

type Tag struct {
	ID    string
	Label string
}

Tag is a label that can be applied to any resource for filtering and organization.

type TagProvider

type TagProvider interface {
	// Create makes a new tag.
	Create(ctx context.Context, label string) (Tag, error)
	// Delete removes a tag and all its associations.
	Delete(ctx context.Context, id string) error
	// Get returns a tag by ID.
	Get(ctx context.Context, id string) (Tag, error)
	// Find returns all tags whose labels contain the query string.
	Find(ctx context.Context, query string) ([]Tag, error)
	// List returns all tags.
	List(ctx context.Context) ([]Tag, error)
	// Apply attaches a tag to one or more resources.
	Apply(ctx context.Context, tagID string, resources []TaggableResource) error
	// Remove detaches a tag from one or more resources.
	Remove(ctx context.Context, tagID string, resources []TaggableResource) error
	// Resources returns all resources that have the given tag.
	Resources(ctx context.Context, tagID string) ([]TaggableResource, error)
	// Tags returns all tags attached to the given resource.
	Tags(ctx context.Context, resource TaggableResource) ([]Tag, error)
}

TagProvider is implemented by a module that stores and manages tags (e.g., tagger).

type TaggableResource

type TaggableResource struct {
	ResourceID   string // e.g., media object ID, profile ID, import list ID
	ResourceType string // e.g., "media_object", "quality_profile", "import_list"
}

TaggableResource identifies what a tag is attached to.

type Task

type Task struct {
	ID       string
	Name     string
	CronExpr string
	Handler  string
	Payload  []byte
	Timeout  int
}

type TaskStatus

type TaskStatus string
const (
	TaskScheduled TaskStatus = "scheduled"
	TaskRunning   TaskStatus = "running"
	TaskCompleted TaskStatus = "completed"
	TaskFailed    TaskStatus = "failed"
	TaskCancelled TaskStatus = "cancelled"
)

type TierTransitionPayload

type TierTransitionPayload struct {
	Key      string      `json:"key"`
	FromTier StorageTier `json:"from_tier"`
	ToTier   StorageTier `json:"to_tier"`
	Reason   string      `json:"reason"`
}

TierTransitionPayload is the payload for storage.tier.transition events.

type TieredProvider

type TieredProvider interface {
	StorageProvider

	// Tier returns which tier this provider handles.
	Tier() StorageTier

	// Promote moves an object from this tier to a higher one.
	Promote(ctx context.Context, key string) error

	// Relegate moves an object from this tier to a lower one.
	Relegate(ctx context.Context, key string) error
}

TieredProvider extends StorageProvider with tiering support. Storage modules that support multiple tiers implement this.

type TranscodeCompletedPayload

type TranscodeCompletedPayload struct {
	MediaID    string `json:"media_id"`
	OutputPath string `json:"output_path"`
}

TranscodeCompletedPayload is the payload for transcode.completed events.

type TranscodeFailedPayload

type TranscodeFailedPayload struct {
	MediaID string `json:"media_id"`
	Error   string `json:"error"`
}

TranscodeFailedPayload is the payload for transcode.failed events.

type TranscodeStartedPayload

type TranscodeStartedPayload struct {
	MediaID string `json:"media_id"`
	Profile string `json:"profile"`
}

TranscodeStartedPayload is the payload for transcode.started events.

type Tx

type Tx interface {
	Exec(ctx context.Context, query string, args ...any) (int64, error)
	Query(ctx context.Context, query string, args ...any) (Rows, error)
}

Tx is a database transaction handle.

type Watchable

type Watchable interface {
	Watch(ctx context.Context, prefix string) (<-chan StorageEvent, error)
}

type WorkerPool

type WorkerPool interface {
	// Submit queues a task for execution. Returns the task ID.
	Submit(ctx context.Context, task WorkerTask) (string, error)

	// Status returns the current state of a task.
	Status(ctx context.Context, taskID string) (WorkerTask, error)

	// Cancel stops a pending or running task.
	Cancel(ctx context.Context, taskID string) error

	// List returns tasks matching the given filter. Nil filter returns all.
	List(ctx context.Context, filter *WorkerTaskFilter) ([]WorkerTask, error)
}

WorkerPool schedules tasks across cluster nodes and tracks their lifecycle.

type WorkerTask

type WorkerTask struct {
	ID            string
	Type          string
	Payload       []byte
	AssignedNode  string
	Status        WorkerTaskStatus
	MaxRetries    int
	RetryCount    int
	Capabilities  []string // required node capabilities (e.g., "gpu", "ssd")
	CreatedAt     time.Time
	StartedAt     time.Time
	CompletedAt   time.Time
	LastHeartbeat time.Time
	Error         string
}

WorkerTask is a unit of work scheduled across the cluster.

type WorkerTaskFilter

type WorkerTaskFilter struct {
	Status       WorkerTaskStatus
	Type         string
	AssignedNode string
}

WorkerTaskFilter narrows task queries.

type WorkerTaskStatus

type WorkerTaskStatus string

WorkerTaskStatus represents the lifecycle of a distributed task.

const (
	WorkerTaskStatusPending   WorkerTaskStatus = "pending"
	WorkerTaskStatusAssigned  WorkerTaskStatus = "assigned"
	WorkerTaskStatusRunning   WorkerTaskStatus = "running"
	WorkerTaskStatusCompleted WorkerTaskStatus = "completed"
	WorkerTaskStatusFailed    WorkerTaskStatus = "failed"
	WorkerTaskStatusCancelled WorkerTaskStatus = "cancelled"
)

type WorkflowDefinition

type WorkflowDefinition struct {
	ID    string
	Name  string
	Steps []WorkflowStep
}

type WorkflowEngine

type WorkflowEngine interface {
	Define(ctx context.Context, def WorkflowDefinition) error
	Run(ctx context.Context, workflowID string, params map[string]any) (string, error)
	Status(ctx context.Context, runID string) (WorkflowRun, error)
	Cancel(ctx context.Context, runID string) error
}

type WorkflowRun

type WorkflowRun struct {
	ID          string
	WorkflowID  string
	Status      string
	CurrentStep int
	Steps       []StepResult
}

type WorkflowStep

type WorkflowStep struct {
	Name    string
	Handler string
	Input   map[string]any
	Retry   int
	Timeout int
}

Jump to

Keyboard shortcuts

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