Documentation
¶
Index ¶
- Constants
- Variables
- func GetContentSegments(content Content) []*metapb.SegmentData
- func HasExtension(filename string) bool
- func NewFileMetadataFromContent(content Content, sourceNzbPath string, releaseDate int64, nzbdavId string) *metapb.FileMetadata
- func ParseInt(s string) int
- func SetKey(filename string) (string, bool)
- func ValidateSegmentIntegrity(ctx context.Context, content Content) error
- type ClipBoundary
- type Content
- type NestedSource
- type RarScheme
Constants ¶
const ( SchemeUnknown = rarname.SchemeUnknown SchemePart = rarname.SchemePart SchemeRoll = rarname.SchemeRoll SchemeNumeric = rarname.SchemeNumeric )
Variables ¶
var ( // ErrNoAllowedFiles indicates that the archive contains no files matching allowed extensions ErrNoAllowedFiles = errors.New("archive contains no files with allowed extensions") // ErrNoFilesProcessed indicates that no files were successfully processed (all files failed validation) ErrNoFilesProcessed = errors.New("no files were successfully processed (all files failed validation)") )
var ( PartPattern = rarname.PartPattern NumericPattern = rarname.NumericPattern RPattern = rarname.RPattern RollVolPattern = rarname.RollVolPattern )
RAR / split-volume filename helpers re-exported from the dependency-free rarname leaf package, which is the single source of truth. They are re-exported here because the rar subpackage already depends on archive and references these names as archive.* (and the sevenzip package aliases archive.PartPattern etc.). The filesystem package imports rarname directly to avoid an import cycle.
Functions ¶
func GetContentSegments ¶
func GetContentSegments(content Content) []*metapb.SegmentData
GetContentSegments returns all segments for a Content, collecting from NestedSources for encrypted nested archive content.
func HasExtension ¶
HasExtension checks if a filename has an extension
func NewFileMetadataFromContent ¶ added in v0.3.0
func NewFileMetadataFromContent( content Content, sourceNzbPath string, releaseDate int64, nzbdavId string, ) *metapb.FileMetadata
NewFileMetadataFromContent creates a FileMetadata from a Content (with its NestedSources) for the metadata system. It mirrors the conversion previously inlined inside rar.CreateFileMetadataFromRarContent and sevenzip.CreateFileMetadataFromSevenZipContent so that non-RAR/non-7z callers (e.g. ISO expansion) can produce equivalent metadata.
Behaviour:
- Sets CreatedAt/ModifiedAt to time.Now().Unix().
- Defaults Status to FILE_STATUS_HEALTHY.
- Copies SegmentData from content.Segments.
- When content.AesKey is non-empty, sets Encryption=AES with key/iv.
- Appends one NestedSegmentSource per content.NestedSources entry.
func SetKey ¶ added in v0.3.0
SetKey returns the multi-volume grouping key for a filename. See rarname.SetKey.
func ValidateSegmentIntegrity ¶
ValidateSegmentIntegrity checks if the segments provided for a file actually cover the expected size. Returns an error if segment coverage is significantly lower than expected (1% shortfall threshold).
Types ¶
type ClipBoundary ¶ added in v0.3.0
ClipBoundary mirrors metapb.ClipBoundary at the archive layer: one clip in a concatenated multi-clip BD main feature. ByteLen is the clip's size in the virtual file; Delta90k is the signed 90 kHz timeline offset for packets inside this clip's byte range.
type Content ¶
type Content struct {
InternalPath string `json:"internal_path"`
Filename string `json:"filename"`
Size int64 `json:"size"` // Uncompressed size (for file metadata)
PackedSize int64 `json:"packed_size"` // Compressed size in archive (for segment validation)
Segments []*metapb.SegmentData `json:"segments"` // Segment data for this file
IsDirectory bool `json:"is_directory,omitempty"` // Indicates if this is a directory
AesKey []byte `json:"aes_key,omitempty"` // AES encryption key (if encrypted)
AesIV []byte `json:"aes_iv,omitempty"` // AES initialization vector (if encrypted)
NzbdavID string `json:"nzbdav_id,omitempty"` // Original ID from nzbdav
NestedSources []NestedSource `json:"nested_sources,omitempty"` // Nested archive sources (encrypted outer)
// ISOExpansionIndex is non-zero for files expanded from an ISO archive.
// It is the 1-based position of this file when all ISO files in the archive
// are sorted by size descending (1 = largest / main feature).
// Zero means this Content did not come from an ISO.
ISOExpansionIndex int `json:"iso_expansion_index,omitempty"`
// ClipBoundaries is the per-clip timeline table for a byte-concatenated
// multi-clip Blu-ray main feature. Empty for everything else. At read
// time a TS filter adds each clip's Delta90k to the timestamps inside
// its byte range to build one continuous timeline.
ClipBoundaries []ClipBoundary `json:"clip_boundaries,omitempty"`
}
Content represents a file within an archive for processing
func ExpandISOContents ¶ added in v0.3.0
func ExpandISOContents( ctx context.Context, expand bool, contents []Content, poolManager pool.Manager, maxPrefetch int, readTimeout time.Duration, analyzeTimeout time.Duration, allowedExtensions []string, progressTracker *progress.Tracker, ) ([]Content, error)
ExpandISOContents replaces .iso entries in contents with the media they contain, applying two Blu-ray-aware optimisations on top of the legacy "pick the largest file" behaviour:
- Within a disc, if BDMV/PLAYLIST/*.mpls identifies a main feature spanning multiple M2TS clips, the clips are virtually concatenated into one Content via NestedSources — the player sees a single file.
- Across discs in the same archive group (e.g. DISC_1 and DISC_2 ISOs in one NZB), discs sharing a stripped volume label are merged so the cross-disc movie also plays as one file.
Non-ISO entries pass through unchanged. Per-ISO errors are non-fatal: on failure the original .iso Content is kept so downstream still has something to work with.
type NestedSource ¶
type NestedSource struct {
Segments []*metapb.SegmentData // Outer archive segments covering this inner volume
AesKey []byte // Outer AES key (empty if unencrypted)
AesIV []byte // Outer AES IV
InnerOffset int64 // Offset within decrypted inner volume where file data starts
InnerLength int64 // Bytes of target file from this source
InnerVolumeSize int64 // Total decrypted size of inner volume (for AES cipher)
}
NestedSource represents one inner archive volume's contribution to a nested file. Used when a file is inside an inner archive that is itself inside an outer archive.