Documentation
¶
Index ¶
- Variables
- func CalculateVirtualDirectory(nzbPath, relativePath string) string
- func CreateDirectoriesForFiles(virtualDir string, files []parser.ParsedFile, ...) error
- func CreateNzbFolder(virtualDir, nzbFilename string, metadataService *metadata.MetadataService) (string, error)
- func DetermineFileLocation(file parser.ParsedFile, baseDir string) (parentPath, filename string)
- func EnsureDirectoryExists(virtualDir string, metadataService *metadata.MetadataService) error
- func EnsureUniqueVirtualPath(virtualPath string, ms *metadata.MetadataService) string
- func IsPar2File(filename string) bool
- func NewAferoAdapter(ufs *UsenetFileSystem) afero.Fs
- func SeparateFiles(files []parser.ParsedFile, nzbType parser.NzbType) (regular, archive, par2 []parser.ParsedFile)
- type AferoAdapter
- func (a *AferoAdapter) Chmod(name string, mode os.FileMode) error
- func (a *AferoAdapter) Chown(name string, uid, gid int) error
- func (a *AferoAdapter) Chtimes(name string, atime time.Time, mtime time.Time) error
- func (a *AferoAdapter) Create(name string) (afero.File, error)
- func (a *AferoAdapter) Mkdir(name string, perm os.FileMode) error
- func (a *AferoAdapter) MkdirAll(path string, perm os.FileMode) error
- func (a *AferoAdapter) Name() string
- func (a *AferoAdapter) Open(name string) (afero.File, error)
- func (a *AferoAdapter) OpenFile(name string, flag int, perm os.FileMode) (afero.File, error)
- func (a *AferoAdapter) Remove(name string) error
- func (a *AferoAdapter) RemoveAll(path string) error
- func (a *AferoAdapter) Rename(oldname, newname string) error
- func (a *AferoAdapter) Stat(name string) (os.FileInfo, error)
- type DecryptingFile
- type DecryptingFileEntry
- type DecryptingFileSystem
- type PathReserver
- type UsenetFile
- type UsenetFileInfo
- type UsenetFileSystem
Constants ¶
This section is empty.
Variables ¶
var ErrReadOnlyFilesystem = errors.New("filesystem is read-only")
Functions ¶
func CalculateVirtualDirectory ¶
CalculateVirtualDirectory determines the virtual directory path based on NZB file location
func CreateDirectoriesForFiles ¶
func CreateDirectoriesForFiles(virtualDir string, files []parser.ParsedFile, metadataService *metadata.MetadataService) error
CreateDirectoriesForFiles analyzes files and creates their parent directories
func CreateNzbFolder ¶
func CreateNzbFolder(virtualDir, nzbFilename string, metadataService *metadata.MetadataService) (string, error)
CreateNzbFolder creates a folder named after the NZB file
func DetermineFileLocation ¶
func DetermineFileLocation(file parser.ParsedFile, baseDir string) (parentPath, filename string)
DetermineFileLocation determines where a file should be placed in the virtual structure
func EnsureDirectoryExists ¶
func EnsureDirectoryExists(virtualDir string, metadataService *metadata.MetadataService) error
EnsureDirectoryExists creates directory structure in the metadata filesystem
func EnsureUniqueVirtualPath ¶ added in v0.3.0
func EnsureUniqueVirtualPath(virtualPath string, ms *metadata.MetadataService) string
EnsureUniqueVirtualPath returns a path that is safe to write to. If a healthy metadata file already exists at virtualPath, appends _1, _2, … to the stem (before the extension) until an unused slot is found. Non-healthy metadata is treated as available to overwrite, so the original path is returned unchanged.
func IsPar2File ¶
IsPar2File checks if a filename is a PAR2 repair file
func NewAferoAdapter ¶
func NewAferoAdapter(ufs *UsenetFileSystem) afero.Fs
NewAferoAdapter creates a new Afero filesystem adapter for UsenetFileSystem
func SeparateFiles ¶
func SeparateFiles(files []parser.ParsedFile, nzbType parser.NzbType) (regular, archive, par2 []parser.ParsedFile)
SeparateFiles separates files by type (regular, archive, PAR2) based on NZB type
Types ¶
type AferoAdapter ¶
type AferoAdapter struct {
// contains filtered or unexported fields
}
AferoAdapter wraps UsenetFileSystem to implement afero.Fs interface This allows sevenzip.OpenReader to use UsenetFileSystem as a custom filesystem
func (*AferoAdapter) MkdirAll ¶
func (a *AferoAdapter) MkdirAll(path string, perm os.FileMode) error
func (*AferoAdapter) Name ¶
func (a *AferoAdapter) Name() string
func (*AferoAdapter) Remove ¶
func (a *AferoAdapter) Remove(name string) error
func (*AferoAdapter) RemoveAll ¶
func (a *AferoAdapter) RemoveAll(path string) error
func (*AferoAdapter) Rename ¶
func (a *AferoAdapter) Rename(oldname, newname string) error
type DecryptingFile ¶
type DecryptingFile struct {
// contains filtered or unexported fields
}
DecryptingFile implements fs.File and io.Seeker for reading an inner RAR volume.
func (*DecryptingFile) Close ¶
func (df *DecryptingFile) Close() error
type DecryptingFileEntry ¶
type DecryptingFileEntry struct {
Filename string
Segments []*metapb.SegmentData
DecryptedSize int64 // Size of the decrypted data
AesKey []byte // Empty = no encryption
AesIV []byte
}
DecryptingFileEntry represents one file in the DecryptingFileSystem. It holds the outer RAR segments and optional AES credentials needed to read (and decrypt) the inner RAR volume at import time.
type DecryptingFileSystem ¶
type DecryptingFileSystem struct {
// contains filtered or unexported fields
}
DecryptingFileSystem implements fs.FS for reading inner RAR archives that are stored inside outer RAR archives on Usenet. When AES credentials are present, it decrypts on-the-fly using AES-CBC. When no credentials are present, it reads raw segments (like UsenetFileSystem).
func NewDecryptingFileSystem ¶
func NewDecryptingFileSystem( ctx context.Context, poolManager pool.Manager, entries []DecryptingFileEntry, maxPrefetch int, readTimeout time.Duration, ) *DecryptingFileSystem
NewDecryptingFileSystem creates a new filesystem for reading inner RAR volumes.
type PathReserver ¶ added in v0.3.0
type PathReserver struct {
// contains filtered or unexported fields
}
PathReserver assigns unique virtual paths within a single import batch, skipping both paths already claimed by sibling goroutines and healthy on-disk metadata.
When many files collide to the same name (e.g. obfuscated Blu-ray BDMV posts where every file inherits the release name), re-probing _1.._k for each file is O(N^2) — and when that probing runs under a single shared lock it also serializes the whole worker pool. PathReserver keeps a per-base "next index" high-water mark so each colliding file claims the next free suffix in O(1) amortized time, behind a short-lived internal lock. Safe for concurrent use.
func NewPathReserver ¶ added in v0.3.0
func NewPathReserver(ms *metadata.MetadataService) *PathReserver
NewPathReserver creates a reserver backed by the given metadata service.
func (*PathReserver) Release ¶ added in v0.3.0
func (r *PathReserver) Release(path string)
Release drops the in-batch claim for path once it is durably on disk.
func (*PathReserver) Reserve ¶ added in v0.3.0
func (r *PathReserver) Reserve(desired string) string
Reserve claims and returns a unique virtual path for desired, appending _1, _2, … only as needed. The caller must Release the returned path once it is durably written (or its write has failed).
type UsenetFile ¶
type UsenetFile struct {
// contains filtered or unexported fields
}
UsenetFile implements fs.File and io.Seeker for reading individual RAR parts from Usenet The Seeker interface allows rardecode.OpenReader to efficiently seek within RAR parts
func (*UsenetFile) Close ¶
func (uf *UsenetFile) Close() error
func (*UsenetFile) ReadAt ¶
func (uf *UsenetFile) ReadAt(p []byte, off int64) (n int, err error)
ReadAt implements io.ReaderAt interface for 7zip access ReadAt reads len(p) bytes into p starting at offset off in the file It returns the number of bytes read and any error encountered
type UsenetFileInfo ¶
type UsenetFileInfo struct {
// contains filtered or unexported fields
}
UsenetFileInfo implements fs.FileInfo for RAR part files
func (*UsenetFileInfo) IsDir ¶
func (ufi *UsenetFileInfo) IsDir() bool
func (*UsenetFileInfo) ModTime ¶
func (ufi *UsenetFileInfo) ModTime() time.Time
func (*UsenetFileInfo) Mode ¶
func (ufi *UsenetFileInfo) Mode() fs.FileMode
func (*UsenetFileInfo) Name ¶
func (ufi *UsenetFileInfo) Name() string
func (*UsenetFileInfo) Size ¶
func (ufi *UsenetFileInfo) Size() int64
func (*UsenetFileInfo) Sys ¶
func (ufi *UsenetFileInfo) Sys() any
type UsenetFileSystem ¶
type UsenetFileSystem struct {
// contains filtered or unexported fields
}
UsenetFileSystem implements fs.FS for reading RAR archives from Usenet This allows rardecode.OpenReader to access multi-part RAR files without downloading them entirely
func NewUsenetFileSystem ¶
func NewUsenetFileSystem(ctx context.Context, poolManager pool.Manager, files []parser.ParsedFile, maxPrefetch int, progressTracker *progress.Tracker, readTimeout time.Duration) *UsenetFileSystem
NewUsenetFileSystem creates a new filesystem for accessing RAR parts from Usenet