container

package
v2.19.0 Latest Latest
Warning

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

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

Documentation

Overview

Package container decides when a directory of indexed media collapses to a single logical launch target, such as a disc folder holding one cue sheet beside its bin tracks. The rule is shared by the MediaDB queries that resolve containers from SQL and by scrapers that resolve them from an in-memory media index, so both agree on what counts as one game.

Index

Constants

View Source
const SourceVirtualScheme = "source"

SourceVirtualScheme matches platforms.SourceScheme (pkg/platforms/source_roots.go). Duplicated here as a literal instead of imported, to avoid an import cycle: pkg/platforms -> pkg/database/scraper -> pkg/database/container.

Variables

This section is empty.

Functions

func MayHaveContainerTarget added in v2.17.1

func MayHaveContainerTarget(mediaPath string) bool

MayHaveContainerTarget reports whether a media path could sit in a directory whose launch target is a different file. Only extensions accepted by the cue, playlist, or shared-title disc-set rules qualify, so a caller holding an ordinary ROM can skip a container lookup entirely. An .m3u itself is excluded because promoting one could only return itself.

func MediaExt

func MediaExt(mediaPath string) string

MediaExt returns the lowercased extension of a slash-separated media path, including the leading dot, or an empty string when there is none.

func ParentDir

func ParentDir(path string) string

ParentDir returns the immediate browse parent of an indexed media path, including the trailing slash. Most virtual media collapses to its scheme prefix because those paths have no directory hierarchy (e.g. an Android app path is scheme://package:variant/Name, always exactly one level deep). A source root path is the one virtual scheme with real nested folders (scheme://id/dir/.../file, walked by mediascanner's source root indexing), so it gets the same last-segment parent a filesystem path gets instead.

Indexed paths are normally stored forward-slashed, but one that reached the row from filepath.Join carries the host separator instead. Searching only for "/" would return nothing for those, and an empty parent resolves to no container at all, silently dropping folder artwork on Windows.

func SelectLaunchMedia

func SelectLaunchMedia(rows []database.Media) *database.Media

SelectLaunchMedia returns the single logical launch target for a directory's direct media rows, or nil when the set is ambiguous. A lone file is its own target; otherwise one m3u playlist or one cue sheet surrounded only by its companion files stands in for the set. A flat set of disc images also collapses when every row belongs to the same known media title.

Types

type Index

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

Index answers container questions from a set of already-loaded media rows. Callers that hold a whole system's media in memory, such as scrapers, use it to resolve directories without issuing a query per candidate.

func NewIndex

func NewIndex(rows []database.Media) *Index

NewIndex builds a container index over rows. Missing media is excluded so the result matches what the equivalent MediaDB queries would return.

func (*Index) HasMedia

func (idx *Index) HasMedia(dirPath string) bool

HasMedia reports whether dirPath holds any direct media rows. It lets callers tell "not a directory we indexed" apart from "a directory that did not collapse".

func (*Index) Resolve

func (idx *Index) Resolve(dirPath string) *database.Media

Resolve returns the single logical launch target for dirPath, or nil when the directory holds nested media, holds nothing, or is ambiguous.

type LaunchSelector added in v2.19.0

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

LaunchSelector applies SelectLaunchMedia's rule to rows added one at a time with a fixed amount of state, so a caller streaming a large system can answer for a few directories without holding every row. The zero value is an empty directory.

func (*LaunchSelector) Add added in v2.19.0

func (s *LaunchSelector) Add(row *database.Media)

Add records one direct media row of the directory.

func (*LaunchSelector) Count added in v2.19.0

func (s *LaunchSelector) Count() int

Count returns how many rows were added.

func (*LaunchSelector) Result added in v2.19.0

func (s *LaunchSelector) Result() *database.Media

Result returns what SelectLaunchMedia would return for the rows added so far, or nil. The returned row is a copy owned by the selector.

type LaunchTargetMap added in v2.19.0

type LaunchTargetMap map[string]database.Media

LaunchTargetMap holds the directories that collapse to a single launch target, keyed by normalized directory.

func (LaunchTargetMap) Resolve added in v2.19.0

func (m LaunchTargetMap) Resolve(dirPath string) *database.Media

Resolve answers as Index.Resolve would.

type LaunchTargets added in v2.19.0

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

LaunchTargets resolves every directory of a system from rows added one at a time, keeping a fixed amount of state per directory rather than every row. Once all rows are added, Map answers Resolve as an Index over them would.

func NewLaunchTargets added in v2.19.0

func NewLaunchTargets() *LaunchTargets

NewLaunchTargets returns an empty LaunchTargets.

func (*LaunchTargets) Add added in v2.19.0

func (t *LaunchTargets) Add(row *database.Media)

Add records one media row under the same rules NewIndex applies.

func (*LaunchTargets) Map added in v2.19.0

func (t *LaunchTargets) Map() LaunchTargetMap

Map returns the launch target of every directory that has one. The per-directory state is released; t must not be used afterwards.

type WatchedIndex added in v2.19.0

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

WatchedIndex answers Index's questions for a fixed set of directories from rows added one at a time. It keeps a fixed amount of state per watched directory rather than every row, so a caller streaming a large system pays for the directories it asks about, not for the system. Its answers for a directory that was not watched are always empty.

func NewWatchedIndex added in v2.19.0

func NewWatchedIndex(dirs []string) *WatchedIndex

NewWatchedIndex returns an index that will answer for dirs.

func (*WatchedIndex) Add added in v2.19.0

func (w *WatchedIndex) Add(row *database.Media)

Add records one media row under the same rules NewIndex applies.

func (*WatchedIndex) HasMedia added in v2.19.0

func (w *WatchedIndex) HasMedia(dirPath string) bool

HasMedia answers as Index.HasMedia would over every added row.

func (*WatchedIndex) Resolve added in v2.19.0

func (w *WatchedIndex) Resolve(dirPath string) *database.Media

Resolve answers as Index.Resolve would over every added row.

Jump to

Keyboard shortcuts

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