Documentation
¶
Index ¶
- func IsPlayable(name string) bool
- type Browser
- func (b *Browser) Config() []config.ExternalMount
- func (b *Browser) IsUserSubpath(mountName string) bool
- func (b *Browser) List(mountName, relPath string) ([]Entry, error)
- func (b *Browser) MigrateToUserSubpath(mountName string, knownUsers map[string]bool, fallbackUser string, ...) (MigrationResult, error)
- func (b *Browser) Mounts() []Mount
- func (b *Browser) MountsFor(username string) []Mount
- func (b *Browser) RemoveEmptyDirs(mountName, relPath string) (int, error)
- func (b *Browser) ResolvePath(mountName, relPath string) (string, error)
- func (b *Browser) ResolvePathFor(mountName, relPath, username string) (string, error)
- func (b *Browser) SetFolderLock(mountName, relPath string, locked bool) error
- func (b *Browser) SetMounts(mounts []config.ExternalMount)
- func (b *Browser) StripUserScope(mountName, username string, entries []Entry) []Entry
- func (b *Browser) UserCanAccess(username, mountName string) bool
- func (b *Browser) UserScopedPath(mountName, relPath, username string) string
- func (b *Browser) Walk(mountName, relPath string, mediaOnly bool) ([]Entry, error)
- type Entry
- type MigratedEntry
- type MigrationResult
- type Mount
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsPlayable ¶
IsPlayable returns true if the filename's extension is a known video/audio type.
Types ¶
type Browser ¶
type Browser struct {
// contains filtered or unexported fields
}
func NewBrowser ¶
func NewBrowser(mounts []config.ExternalMount) *Browser
func (*Browser) Config ¶
func (b *Browser) Config() []config.ExternalMount
Config returns a copy of the raw mount config (admin-only; includes AllowedUsers).
func (*Browser) IsUserSubpath ¶
IsUserSubpath reports whether the named mount uses per-user subdirectories.
func (*Browser) MigrateToUserSubpath ¶
func (b *Browser) MigrateToUserSubpath(mountName string, knownUsers map[string]bool, fallbackUser string, attribute func(absPath string) (string, bool)) (MigrationResult, error)
MigrateToUserSubpath relocates loose entries at a UserSubpath mount's root into per-user subdirs (mount/{username}/...), so flipping a previously-shared mount to per-user doesn't orphan existing files.
attribute maps an entry's absolute path to (username, true) when an owner is known; entries it can't attribute (or whose owner isn't a known user) go to fallbackUser. knownUsers is the set of valid usernames: a root *directory* whose name is a known user is treated as already-scoped and left untouched, which makes the operation idempotent (safe to run on every boot). Moves use os.Rename — atomic and copy-free since source and dest share the mount root.
func (*Browser) MountsFor ¶
MountsFor returns mounts visible to the given username. Empty username = only public mounts (AllowedUsers empty).
func (*Browser) RemoveEmptyDirs ¶
RemoveEmptyDirs deletes empty subdirectories under relPath inside the mount, bottom-up so a directory that only held now-removed empty children is itself removed. Returns how many directories were deleted.
Safety: the start directory itself and the mount root are never removed; hidden dirs (".thumbs", ".artwork", …) are skipped entirely; os.Remove only succeeds on a truly empty dir (non-empty → ENOTEMPTY, ignored). Path traversal is already guarded by ResolvePath.
func (*Browser) ResolvePath ¶
ResolvePath joins mount.Path with relPath safely, rejecting any attempt to escape the mount root via "..", absolute paths, or symlink-like trickery. Returns the absolute path on disk.
func (*Browser) ResolvePathFor ¶
ResolvePathFor is like ResolvePath but respects UserSubpath mounts for the given user.
func (*Browser) SetFolderLock ¶
SetFolderLock pins (locked=true) or unpins a directory by creating/removing the keep marker inside it. Pinned folders survive RemoveEmptyDirs. The path must resolve to a directory inside the mount (ResolvePath guards traversal); the mount root itself can't be pinned. Idempotent: locking an already-locked folder (or unlocking an unlocked one) is a no-op success.
func (*Browser) SetMounts ¶
func (b *Browser) SetMounts(mounts []config.ExternalMount)
SetMounts swaps the live mount configuration (used by the admin mounts editor so changes apply without a restart).
func (*Browser) StripUserScope ¶
StripUserScope removes the leading username prefix from Entry paths for UserSubpath mounts, so the frontend sees paths as if the mount root were the user's personal subdir.
func (*Browser) UserCanAccess ¶
UserCanAccess checks if a username is allowed to access a given mount name. It iterates effectiveMounts (NOT the raw snapshot) so an unrestricted duplicate can never grant access that its restricted twin denies.
func (*Browser) UserScopedPath ¶
UserScopedPath prepends the username to relPath for UserSubpath mounts. For regular mounts, returns relPath unchanged. Safe to use on all mounts.
type Entry ¶
type Entry struct {
Name string `json:"name"`
Path string `json:"path"`
IsDir bool `json:"isDir"`
Size int64 `json:"size"`
ModTime time.Time `json:"modTime"`
IsPlayable bool `json:"isPlayable"`
// ChildCount is the number of (non-hidden) entries directly inside a
// directory — shown in the UI where files show their size. 0 for files.
ChildCount int `json:"childCount"`
// Locked marks a directory the user pinned (a ".keep" marker inside) so
// "clean empty folders" never removes it even when it holds no files.
Locked bool `json:"locked,omitempty"`
// Incomplete flags a download still in progress: a ".part" file, or a
// directory whose tree still holds one. Lets the browser show a "baixando"
// indicator instead of presenting a half-written file as if it were ready.
Incomplete bool `json:"incomplete,omitempty"`
}
type MigratedEntry ¶
type MigratedEntry struct {
Name string // the entry's filename at the (old) mount root
ToUser string // the username subdir it was moved into
Fallback bool // true when attribution failed and it went to fallbackUser
}
MigratedEntry records one relocated root entry during a UserSubpath migration.
type MigrationResult ¶
type MigrationResult struct {
Mount string
Moved []MigratedEntry
Skipped int // entries already inside a known user's subdir (idempotency)
Active int // entries left in place because they're downloads in progress (.part)
Conflicts int // entries left in place because the per-user dest already exists
}
MigrationResult summarizes a MigrateToUserSubpath run.