Documentation
¶
Index ¶
- Constants
- Variables
- func CalculateAbsoluteOffset(text string, line, charPos int) int
- func DecodeToUTF8(raw []byte, enc TextEncoding) (string, bool)
- func EncodeFromUTF8(s string, enc TextEncoding) []byte
- func IsFileSizeError(err error) bool
- func IsTimeoutError(err error) bool
- func LooksLikeText(buf []byte) bool
- func ShouldPreprocess(filePath string) bool
- type AudioMetadataPreprocessor
- func (amp *AudioMetadataPreprocessor) CanProcess(filePath string) bool
- func (amp *AudioMetadataPreprocessor) GetName() string
- func (amp *AudioMetadataPreprocessor) GetSupportedExtensions() []string
- func (amp *AudioMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
- func (amp *AudioMetadataPreprocessor) SetObserver(observer observability.Observer)
- type BaseMetadataPreprocessor
- func (bmp *BaseMetadataPreprocessor) AddRetryDelay(attemptCount int)
- func (bmp *BaseMetadataPreprocessor) ApplyConfig(config *MetadataProcessingConfig)
- func (bmp *BaseMetadataPreprocessor) BuildErrorContent(filePath, format string, err error) *ProcessedContent
- func (bmp *BaseMetadataPreprocessor) BuildSuccessContent(filePath, text, format string, pageCount int) *ProcessedContent
- func (bmp *BaseMetadataPreprocessor) CreateProcessingContext() (context.Context, context.CancelFunc)
- func (bmp *BaseMetadataPreprocessor) GetName() string
- func (bmp *BaseMetadataPreprocessor) GetObserver() observability.Observer
- func (bmp *BaseMetadataPreprocessor) GetRouter() RouterInterface
- func (bmp *BaseMetadataPreprocessor) GetUtilities() *SharedUtilities
- func (bmp *BaseMetadataPreprocessor) HandleError(filePath, fileType string, err error) *ProcessedContent
- func (bmp *BaseMetadataPreprocessor) LogDebugInfo(message string)
- func (bmp *BaseMetadataPreprocessor) LogFileSystemInfo(filename string, fileSize int64, mimeType string)
- func (bmp *BaseMetadataPreprocessor) LogRetryAttempt(filePath string, attemptCount int)
- func (bmp *BaseMetadataPreprocessor) LogSuccessfulProcessing(filename string, fileSize int64, mimeType string)
- func (bmp *BaseMetadataPreprocessor) ProcessEmbeddedMedia(originalFilePath string, embeddedMedia []EmbeddedMedia) (string, []ContentSection, []string)
- func (bmp *BaseMetadataPreprocessor) ProcessWithRetry(filePath string, processFunc func() (*ProcessedContent, error)) (*ProcessedContent, error)
- func (bmp *BaseMetadataPreprocessor) SetObserver(observer observability.Observer)
- func (bmp *BaseMetadataPreprocessor) SetRouter(router RouterInterface)
- func (bmp *BaseMetadataPreprocessor) ShouldRetry(err error, attemptCount int) bool
- func (bmp *BaseMetadataPreprocessor) ValidateFileSize(filePath string, isVideo bool) error
- type BoundingBox
- type ContentSection
- type DocumentPosition
- type EmbeddedMedia
- type ErrorClassifier
- type ErrorLogger
- type ErrorRecoveryManager
- type ErrorType
- type FileExtensionValidator
- func (fev *FileExtensionValidator) GetAudioExtensions() []string
- func (fev *FileExtensionValidator) GetFileExtension(filePath string) string
- func (fev *FileExtensionValidator) GetFileName(filePath string) string
- func (fev *FileExtensionValidator) GetImageExtensions() []string
- func (fev *FileExtensionValidator) GetOfficeExtensions() []string
- func (fev *FileExtensionValidator) GetPDFExtensions() []string
- func (fev *FileExtensionValidator) GetVideoExtensions() []string
- func (fev *FileExtensionValidator) IsAudioFile(filePath string) bool
- func (fev *FileExtensionValidator) IsImageFile(filePath string) bool
- func (fev *FileExtensionValidator) IsOfficeFile(filePath string) bool
- func (fev *FileExtensionValidator) IsPDFFile(filePath string) bool
- func (fev *FileExtensionValidator) IsVideoFile(filePath string) bool
- type GracefulDegradationHandler
- type ImageMetadataPreprocessor
- func (imp *ImageMetadataPreprocessor) CanProcess(filePath string) bool
- func (imp *ImageMetadataPreprocessor) GetName() string
- func (imp *ImageMetadataPreprocessor) GetSupportedExtensions() []string
- func (imp *ImageMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
- func (imp *ImageMetadataPreprocessor) SetObserver(observer observability.Observer)
- type LogLevel
- type MediaProcessingError
- func (mpe *MediaProcessingError) Error() string
- func (mpe *MediaProcessingError) GetContext() map[string]interface{}
- func (mpe *MediaProcessingError) GetErrorType() ErrorType
- func (mpe *MediaProcessingError) IsRecoverable() bool
- func (mpe *MediaProcessingError) Unwrap() error
- func (mpe *MediaProcessingError) WithContext(key string, value interface{}) *MediaProcessingError
- type MediaResourceManager
- func (rm *MediaResourceManager) CreateProcessingContext() (context.Context, context.CancelFunc)
- func (rm *MediaResourceManager) GetLimits() *ResourceLimits
- func (rm *MediaResourceManager) SetLimits(limits *ResourceLimits)
- func (rm *MediaResourceManager) ValidateFileSize(filePath string, isVideo bool) error
- type MetadataFormatter
- func (mf *MetadataFormatter) CalculateTextMetrics(text string) (wordCount, charCount, lineCount int)
- func (mf *MetadataFormatter) FormatBooleanField(key string, value bool) string
- func (mf *MetadataFormatter) FormatDateField(key string, date time.Time) string
- func (mf *MetadataFormatter) FormatMetadataField(key, value string) string
- func (mf *MetadataFormatter) FormatNumericField(key string, value int) string
- func (mf *MetadataFormatter) FormatPropertiesMap(properties map[string]string, excludeKeys []string) string
- type MetadataProcessingConfig
- type OfficeMetadataPreprocessor
- func (omp *OfficeMetadataPreprocessor) CanProcess(filePath string) bool
- func (omp *OfficeMetadataPreprocessor) GetSupportedExtensions() []string
- func (omp *OfficeMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
- func (omp *OfficeMetadataPreprocessor) SetObserver(observer observability.Observer)
- func (omp *OfficeMetadataPreprocessor) SetRouter(router RouterInterface)
- type PDFMetadataPreprocessor
- func (pmp *PDFMetadataPreprocessor) CanProcess(filePath string) bool
- func (pmp *PDFMetadataPreprocessor) GetSupportedExtensions() []string
- func (pmp *PDFMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
- func (pmp *PDFMetadataPreprocessor) SetObserver(observer observability.Observer)
- func (pmp *PDFMetadataPreprocessor) SetRouter(router RouterInterface)
- type PlainTextPreprocessor
- func (ptp *PlainTextPreprocessor) CanProcess(filePath string) bool
- func (ptp *PlainTextPreprocessor) GetName() string
- func (ptp *PlainTextPreprocessor) GetSupportedExtensions() []string
- func (ptp *PlainTextPreprocessor) Process(filePath string) (*ProcessedContent, error)
- func (ptp *PlainTextPreprocessor) SetObserver(observer observability.Observer)
- type PositionMapping
- type Preprocessor
- type PreprocessorManager
- func (pm *PreprocessorManager) GetAvailablePreprocessors() []Preprocessor
- func (pm *PreprocessorManager) GetPreprocessor(filePath string) Preprocessor
- func (pm *PreprocessorManager) ProcessFile(filePath string) (*ProcessedContent, error)
- func (pm *PreprocessorManager) RegisterPreprocessor(p Preprocessor)
- type ProcessedContent
- func (pc *ProcessedContent) AddPositionMapping(mapping PositionMapping)
- func (pc *ProcessedContent) AddPositionMetadata(key string, value interface{})
- func (pc *ProcessedContent) EnablePositionTracking()
- func (pc *ProcessedContent) GetPositionMappingsForRange(startLine, startChar, endLine, endChar int) []PositionMapping
- func (pc *ProcessedContent) SetPositionConfidence(confidence float64)
- type ProcessedContentBuilder
- type ProcessingError
- type RecoveryStrategy
- type ResourceLimits
- type RouterIntegrationHelper
- type RouterInterface
- type SectionKind
- type SharedUtilities
- type TextEncoding
- type TextPosition
- type TextPreprocessor
- func (tp *TextPreprocessor) CanProcess(filePath string) bool
- func (tp *TextPreprocessor) GetName() string
- func (tp *TextPreprocessor) GetSupportedExtensions() []string
- func (tp *TextPreprocessor) Process(filePath string) (*ProcessedContent, error)
- func (tp *TextPreprocessor) SetObserver(observer observability.Observer)
- type VideoMetadataPreprocessor
- func (vmp *VideoMetadataPreprocessor) CanProcess(filePath string) bool
- func (vmp *VideoMetadataPreprocessor) GetSupportedExtensions() []string
- func (vmp *VideoMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
- func (vmp *VideoMetadataPreprocessor) SetObserver(observer observability.Observer)
- func (vmp *VideoMetadataPreprocessor) SetRouter(router RouterInterface)
Constants ¶
const ( ProcessorTypeImageMetadata = "image_metadata" ProcessorTypePDFMetadata = "pdf_metadata" ProcessorTypeOfficeMetadata = "office_metadata" ProcessorTypeAudioMetadata = "audio_metadata" ProcessorTypeVideoMetadata = "video_metadata" )
ProcessorType constants for specialized metadata preprocessors
const ( FormatImageMetadata = "image_metadata" FormatPDFMetadata = "pdf_metadata" FormatOfficeMetadata = "office_metadata" FormatAudioMetadata = "audio_metadata" FormatVideoMetadata = "video_metadata" )
Format constants for processed content
const ( PreprocessorNameImage = "image_metadata_preprocessor" PreprocessorNamePDF = "pdf_metadata_preprocessor" PreprocessorNameOffice = "office_metadata_preprocessor" PreprocessorNameAudio = "audio_metadata_preprocessor" PreprocessorNameVideo = "video_metadata_preprocessor" )
Preprocessor name constants
const ( FileTypeImage = "image" FileTypePDF = "pdf" FileTypeOffice = "office" FileTypeAudio = "audio" FileTypeVideo = "video" )
File type constants for error handling and logging
const ( MetadataFieldTitle = "Title" MetadataFieldAuthor = "Author" MetadataFieldSubject = "Subject" MetadataFieldKeywords = "Keywords" MetadataFieldCreator = "Creator" MetadataFieldProducer = "Producer" MetadataFieldCreationDate = "CreationDate" MetadataFieldModificationDate = "ModificationDate" MetadataFieldPageCount = "PageCount" MetadataFieldWordCount = "WordCount" MetadataFieldCharacterCount = "CharacterCount" MetadataFieldDescription = "Description" MetadataFieldCategory = "Category" MetadataFieldApplication = "Application" MetadataFieldApplicationVersion = "ApplicationVersion" MetadataFieldCompany = "Company" MetadataFieldLastModifiedBy = "LastModifiedBy" MetadataFieldManager = "Manager" MetadataFieldComments = "Comments" MetadataFieldContentStatus = "ContentStatus" MetadataFieldIdentifier = "Identifier" MetadataFieldLanguage = "Language" MetadataFieldRevision = "Revision" MetadataFieldPDFVersion = "PDFVersion" MetadataFieldEncrypted = "Encrypted" )
Common metadata field names for consistent formatting
const (
MetadataDateFormat = "2006:01:02 15:04:05-07:00"
)
Date format constant for consistent date formatting
Variables ¶
var (
CommonDateExclusionKeys = []string{
"CreationDate",
"ModificationDate",
}
)
Common exclusion keys for properties formatting
var ErrEmbeddedTooDeep = embedded.ErrTooDeep
ErrEmbeddedTooDeep is returned by RouterInterface.ProcessEmbedded when a container nests deeper than the router's bound.
A sentinel rather than a formatted string so the caller can branch on it with errors.Is and tell "too deep" (coverage was cut short — say so) apart from "this child failed to parse" (already handled by the ordinary error path).
Aliased to embedded.ErrTooDeep rather than declared independently: the redaction side raises the same condition, and two distinct sentinels would make errors.Is fail across the halves — a caller branching on the read side's value would not recognise the write side's, and the "coverage was cut short" disclosure would be silently downgraded to a generic failure. Existing references to this name keep working.
Functions ¶
func CalculateAbsoluteOffset ¶
CalculateAbsoluteOffset calculates the absolute character offset for a text position
func DecodeToUTF8 ¶ added in v2.1.2
func DecodeToUTF8(raw []byte, enc TextEncoding) (string, bool)
DecodeToUTF8 decodes raw file bytes to a UTF-8 string according to enc. Decoding is total: malformed sequences (lone surrogates, a truncated final code unit) decode to U+FFFD rather than failing — a corrupt tail must not hide the readable remainder of a file from scanning. The second return is false only when enc is not a transcodable encoding (caller keeps raw).
func EncodeFromUTF8 ¶ added in v2.1.2
func EncodeFromUTF8(s string, enc TextEncoding) []byte
EncodeFromUTF8 re-encodes a UTF-8 string back to enc, restoring the BOM where the source had one. Used by the redaction write path so a redacted copy of a UTF-16 file is still a valid UTF-16 file (a re-importable .reg export, a PowerShell transcript, ...) rather than silently becoming UTF-8.
func IsFileSizeError ¶
IsFileSizeError checks if the error is a file size limit error
func IsTimeoutError ¶
IsTimeoutError checks if the error is a timeout error
func LooksLikeText ¶ added in v2.1.1
LooksLikeText reports whether buf (a null-free prefix of the file) is text. Exported because the FileRouter maintains a second sniff site (isTextFile in internal/router) that must apply identical semantics — the two copies of the old byte-ratio heuristic drifted into the same UTF-8 bug independently.
UTF-8 first: every byte of a multi-byte UTF-8 sequence is >= 0x80, so the old ASCII-printable ratio counted EVERY non-ASCII character against the file. A short line with a ™ (3 bytes) or an em-dash, a name with accents, or any non-Latin-script document fell below the 95% bar and the file was silently skipped as "binary" — a recall hole across ALL validators in file mode (stdin mode never sniffs, which is how the gap hid). Genuinely binary data essentially never forms long runs of valid UTF-8, so utf8.Valid is both the safer and the stricter signal; the ASCII-ratio heuristic remains only as the fallback for legacy single-byte encodings (Latin-1 etc.), which are not valid UTF-8 but are still text someone may want scanned.
func ShouldPreprocess ¶
ShouldPreprocess checks if a file should be preprocessed based on its extension Now returns true for all files since we have a plain text preprocessor that handles all file types
Types ¶
type AudioMetadataPreprocessor ¶
type AudioMetadataPreprocessor struct {
// contains filtered or unexported fields
}
AudioMetadataPreprocessor extracts metadata from audio files
func NewAudioMetadataPreprocessor ¶
func NewAudioMetadataPreprocessor() *AudioMetadataPreprocessor
NewAudioMetadataPreprocessor creates a new audio metadata preprocessor
func (*AudioMetadataPreprocessor) CanProcess ¶
func (amp *AudioMetadataPreprocessor) CanProcess(filePath string) bool
CanProcess checks if this preprocessor can handle the given file
func (*AudioMetadataPreprocessor) GetName ¶
func (amp *AudioMetadataPreprocessor) GetName() string
GetName returns the name of this preprocessor
func (*AudioMetadataPreprocessor) GetSupportedExtensions ¶
func (amp *AudioMetadataPreprocessor) GetSupportedExtensions() []string
GetSupportedExtensions returns the file extensions this preprocessor supports
func (*AudioMetadataPreprocessor) Process ¶
func (amp *AudioMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
Process extracts metadata from audio files
func (*AudioMetadataPreprocessor) SetObserver ¶
func (amp *AudioMetadataPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
type BaseMetadataPreprocessor ¶
type BaseMetadataPreprocessor struct {
// contains filtered or unexported fields
}
BaseMetadataPreprocessor provides common functionality for all specialized metadata preprocessors
func NewBaseMetadataPreprocessor ¶
func NewBaseMetadataPreprocessor(name, processorType string) *BaseMetadataPreprocessor
NewBaseMetadataPreprocessor creates a new base metadata preprocessor
func (*BaseMetadataPreprocessor) AddRetryDelay ¶
func (bmp *BaseMetadataPreprocessor) AddRetryDelay(attemptCount int)
AddRetryDelay adds a small delay before retry attempts
func (*BaseMetadataPreprocessor) ApplyConfig ¶
func (bmp *BaseMetadataPreprocessor) ApplyConfig(config *MetadataProcessingConfig)
ApplyConfig applies configuration to the base preprocessor
func (*BaseMetadataPreprocessor) BuildErrorContent ¶
func (bmp *BaseMetadataPreprocessor) BuildErrorContent(filePath, format string, err error) *ProcessedContent
BuildErrorContent creates a failed ProcessedContent structure
func (*BaseMetadataPreprocessor) BuildSuccessContent ¶
func (bmp *BaseMetadataPreprocessor) BuildSuccessContent(filePath, text, format string, pageCount int) *ProcessedContent
BuildSuccessContent creates a successful ProcessedContent structure
func (*BaseMetadataPreprocessor) CreateProcessingContext ¶
func (bmp *BaseMetadataPreprocessor) CreateProcessingContext() (context.Context, context.CancelFunc)
CreateProcessingContext creates a context with timeout for processing
func (*BaseMetadataPreprocessor) GetName ¶
func (bmp *BaseMetadataPreprocessor) GetName() string
GetName returns the name of this preprocessor
func (*BaseMetadataPreprocessor) GetObserver ¶
func (bmp *BaseMetadataPreprocessor) GetObserver() observability.Observer
GetObserver returns the observer instance
func (*BaseMetadataPreprocessor) GetRouter ¶
func (bmp *BaseMetadataPreprocessor) GetRouter() RouterInterface
GetRouter returns the router instance
func (*BaseMetadataPreprocessor) GetUtilities ¶
func (bmp *BaseMetadataPreprocessor) GetUtilities() *SharedUtilities
GetUtilities returns the shared utilities instance
func (*BaseMetadataPreprocessor) HandleError ¶
func (bmp *BaseMetadataPreprocessor) HandleError(filePath, fileType string, err error) *ProcessedContent
HandleError handles processing errors with comprehensive error handling
func (*BaseMetadataPreprocessor) LogDebugInfo ¶
func (bmp *BaseMetadataPreprocessor) LogDebugInfo(message string)
LogDebugInfo logs debug information if observer is available
func (*BaseMetadataPreprocessor) LogFileSystemInfo ¶
func (bmp *BaseMetadataPreprocessor) LogFileSystemInfo(filename string, fileSize int64, mimeType string)
LogFileSystemInfo logs file system information for observability (excluded from validator content)
func (*BaseMetadataPreprocessor) LogRetryAttempt ¶
func (bmp *BaseMetadataPreprocessor) LogRetryAttempt(filePath string, attemptCount int)
LogRetryAttempt logs retry attempt information
func (*BaseMetadataPreprocessor) LogSuccessfulProcessing ¶
func (bmp *BaseMetadataPreprocessor) LogSuccessfulProcessing(filename string, fileSize int64, mimeType string)
LogSuccessfulProcessing logs successful processing information
func (*BaseMetadataPreprocessor) ProcessEmbeddedMedia ¶
func (bmp *BaseMetadataPreprocessor) ProcessEmbeddedMedia(originalFilePath string, embeddedMedia []EmbeddedMedia) (string, []ContentSection, []string)
ProcessEmbeddedMedia processes embedded media through the router if available.
It returns the text to append to the container's own metadata text, AND one ContentSection per embedded item describing that text out of band. The sections' LineOffset values are relative to the START OF THE RETURNED TEXT; the caller shifts them by the length of whatever it puts in front.
The sections matter because an embedded item is a section INSIDE one preprocessor's output, and it routes to a DIFFERENT metadata rule set than its container: a .wav inside a .docx carries an "Artist:" field, which is on the audio rule list but not the office one. Without a declared sub-section the whole blob would be labelled office_metadata and that field would report nothing. Measured: the AUTHOR_INFO finding for an embedded clip's artist address disappeared until these sections were carried. ProcessEmbeddedMedia now also returns WARNINGS: notes about embedded items it could not descend into. An item skipped silently is undisclosed missing coverage, which is the failure mode this whole area keeps producing.
func (*BaseMetadataPreprocessor) ProcessWithRetry ¶
func (bmp *BaseMetadataPreprocessor) ProcessWithRetry(filePath string, processFunc func() (*ProcessedContent, error)) (*ProcessedContent, error)
ProcessWithRetry provides a generic retry mechanism for metadata processing
func (*BaseMetadataPreprocessor) SetObserver ¶
func (bmp *BaseMetadataPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
func (*BaseMetadataPreprocessor) SetRouter ¶
func (bmp *BaseMetadataPreprocessor) SetRouter(router RouterInterface)
SetRouter sets the router instance for reprocessing embedded media
func (*BaseMetadataPreprocessor) ShouldRetry ¶
func (bmp *BaseMetadataPreprocessor) ShouldRetry(err error, attemptCount int) bool
ShouldRetry determines if processing should be retried based on error type and attempt count
func (*BaseMetadataPreprocessor) ValidateFileSize ¶
func (bmp *BaseMetadataPreprocessor) ValidateFileSize(filePath string, isVideo bool) error
ValidateFileSize validates file size based on file type
type BoundingBox ¶
type BoundingBox struct {
// X is the left coordinate (normalized 0.0-1.0 or absolute pixels)
X float64 `json:"x"`
// Y is the top coordinate (normalized 0.0-1.0 or absolute pixels)
Y float64 `json:"y"`
// Width is the width of the box
Width float64 `json:"width"`
// Height is the height of the box
Height float64 `json:"height"`
// Unit indicates the coordinate system ("normalized", "pixels", "points")
Unit string `json:"unit,omitempty"`
}
BoundingBox represents a rectangular area in a document
type ContentSection ¶ added in v2.2.1
type ContentSection struct {
// Name is the producing preprocessor's GetName(), e.g. "Text Extractor" or
// "office_metadata". This is the string the flat separator used to spell out.
Name string
// Kind is the routing decision: SectionKindBody or SectionKindMetadata.
Kind SectionKind
// Type is the metadata preprocessor type ("office_metadata",
// "image_metadata", ...) for a metadata section, and empty for a body
// section. It is what the METADATA validator keys its per-preprocessor
// field rules off.
Type string
// SourceFile is the path to attribute findings in this section to. It is the
// scanned file for a normal section, and the "container.docx -> image1.jpg"
// form for a section extracted from embedded media.
SourceFile string
// Text is this section's bytes. It is a substring of ProcessedContent.Text
// (Go strings share backing storage, so this is a reference, not a copy).
Text string
// LineOffset is the 0-based line index at which Text begins within
// ProcessedContent.Text, so a finding's line number inside a section can be
// reported against the whole extracted document.
LineOffset int
}
ContentSection describes one contiguous run of ProcessedContent.Text and where it came from. Every field is derived from OUR OWN code — the preprocessor's GetName() and the router's classification of it — never from the scanned document's bytes. That provenance is the entire point: it is what makes a section boundary unforgeable by a document author.
type DocumentPosition ¶
type DocumentPosition struct {
// Page is the page number (1-based, 0 for single-page documents)
Page int `json:"page"`
// BoundingBox defines the rectangular area in the document (for PDFs, images, etc.)
BoundingBox *BoundingBox `json:"bounding_box,omitempty"`
// TextRun is the text run identifier (for structured documents)
TextRun int `json:"text_run,omitempty"`
// CharOffset is the character offset within the original document
CharOffset int `json:"char_offset"`
// LineNumber is the line number in the original document (if applicable)
LineNumber int `json:"line_number,omitempty"`
}
DocumentPosition represents a position in the original document
type EmbeddedMedia ¶
EmbeddedMedia represents embedded media extracted from documents
type ErrorClassifier ¶
type ErrorClassifier struct{}
ErrorClassifier classifies errors into appropriate types
func NewErrorClassifier ¶
func NewErrorClassifier() *ErrorClassifier
NewErrorClassifier creates a new error classifier
func (*ErrorClassifier) ClassifyError ¶
func (ec *ErrorClassifier) ClassifyError(err error) ErrorType
ClassifyError classifies an error into an appropriate ErrorType
type ErrorLogger ¶
type ErrorLogger struct {
// contains filtered or unexported fields
}
ErrorLogger provides structured logging for media processing errors
func NewErrorLogger ¶
func NewErrorLogger(level LogLevel) *ErrorLogger
NewErrorLogger creates a new error logger
func (*ErrorLogger) LogError ¶
func (el *ErrorLogger) LogError(err *MediaProcessingError)
LogError logs a media processing error with appropriate level
type ErrorRecoveryManager ¶
type ErrorRecoveryManager struct {
// contains filtered or unexported fields
}
ErrorRecoveryManager manages error recovery strategies
func NewErrorRecoveryManager ¶
func NewErrorRecoveryManager() *ErrorRecoveryManager
NewErrorRecoveryManager creates a new error recovery manager
func (*ErrorRecoveryManager) GetMaxRetries ¶
func (erm *ErrorRecoveryManager) GetMaxRetries() int
GetMaxRetries returns the maximum number of retries
func (*ErrorRecoveryManager) GetRecoveryStrategy ¶
func (erm *ErrorRecoveryManager) GetRecoveryStrategy(errorType ErrorType) RecoveryStrategy
GetRecoveryStrategy returns the recovery strategy for an error type
func (*ErrorRecoveryManager) SetMaxRetries ¶
func (erm *ErrorRecoveryManager) SetMaxRetries(maxRetries int)
SetMaxRetries sets the maximum number of retries
func (*ErrorRecoveryManager) ShouldRetry ¶
func (erm *ErrorRecoveryManager) ShouldRetry(errorType ErrorType, attemptCount int) bool
ShouldRetry determines if an error should trigger a retry
type ErrorType ¶
type ErrorType string
ErrorType represents different types of processing errors
const ( // File-related errors ErrorTypeFileAccess ErrorType = "file_access" ErrorTypeFileSize ErrorType = "file_size" ErrorTypeFileCorrupted ErrorType = "file_corrupted" // Format-related errors ErrorTypeUnsupportedFormat ErrorType = "unsupported_format" ErrorTypeInvalidFormat ErrorType = "invalid_format" ErrorTypeFormatCorrupted ErrorType = "format_corrupted" // Processing-related errors ErrorTypeTimeout ErrorType = "timeout" ErrorTypeMemoryLimit ErrorType = "memory_limit" ErrorTypeParsingFailed ErrorType = "parsing_failed" ErrorTypeExtractionFailed ErrorType = "extraction_failed" // Context-related errors ErrorTypeCancelled ErrorType = "cancelled" // Unknown errors ErrorTypeUnknown ErrorType = "unknown" )
type FileExtensionValidator ¶
type FileExtensionValidator struct {
// contains filtered or unexported fields
}
FileExtensionValidator provides common file extension validation functions
func NewFileExtensionValidator ¶
func NewFileExtensionValidator() *FileExtensionValidator
NewFileExtensionValidator creates a new file extension validator
func (*FileExtensionValidator) GetAudioExtensions ¶
func (fev *FileExtensionValidator) GetAudioExtensions() []string
GetAudioExtensions returns all supported audio extensions
func (*FileExtensionValidator) GetFileExtension ¶
func (fev *FileExtensionValidator) GetFileExtension(filePath string) string
GetFileExtension returns the lowercase file extension
func (*FileExtensionValidator) GetFileName ¶
func (fev *FileExtensionValidator) GetFileName(filePath string) string
GetFileName extracts the filename from a file path
func (*FileExtensionValidator) GetImageExtensions ¶
func (fev *FileExtensionValidator) GetImageExtensions() []string
GetImageExtensions returns all supported image extensions
func (*FileExtensionValidator) GetOfficeExtensions ¶
func (fev *FileExtensionValidator) GetOfficeExtensions() []string
GetOfficeExtensions returns all supported Office extensions
func (*FileExtensionValidator) GetPDFExtensions ¶
func (fev *FileExtensionValidator) GetPDFExtensions() []string
GetPDFExtensions returns all supported PDF extensions
func (*FileExtensionValidator) GetVideoExtensions ¶
func (fev *FileExtensionValidator) GetVideoExtensions() []string
GetVideoExtensions returns all supported video extensions
func (*FileExtensionValidator) IsAudioFile ¶
func (fev *FileExtensionValidator) IsAudioFile(filePath string) bool
IsAudioFile checks if the file is an audio file
func (*FileExtensionValidator) IsImageFile ¶
func (fev *FileExtensionValidator) IsImageFile(filePath string) bool
IsImageFile checks if the file is an image file
func (*FileExtensionValidator) IsOfficeFile ¶
func (fev *FileExtensionValidator) IsOfficeFile(filePath string) bool
IsOfficeFile checks if the file is an Office document
func (*FileExtensionValidator) IsPDFFile ¶
func (fev *FileExtensionValidator) IsPDFFile(filePath string) bool
IsPDFFile checks if the file is a PDF file
func (*FileExtensionValidator) IsVideoFile ¶
func (fev *FileExtensionValidator) IsVideoFile(filePath string) bool
IsVideoFile checks if the file is a video file
type GracefulDegradationHandler ¶
type GracefulDegradationHandler struct {
// contains filtered or unexported fields
}
GracefulDegradationHandler handles graceful degradation for different error types
func NewGracefulDegradationHandler ¶
func NewGracefulDegradationHandler() *GracefulDegradationHandler
NewGracefulDegradationHandler creates a new graceful degradation handler
func (*GracefulDegradationHandler) HandleError ¶
func (gdh *GracefulDegradationHandler) HandleError(filePath, fileType string, err error) *ProcessedContent
HandleError handles an error with graceful degradation
type ImageMetadataPreprocessor ¶
type ImageMetadataPreprocessor struct {
// contains filtered or unexported fields
}
ImageMetadataPreprocessor extracts metadata from image files
func NewImageMetadataPreprocessor ¶
func NewImageMetadataPreprocessor() *ImageMetadataPreprocessor
NewImageMetadataPreprocessor creates a new image metadata preprocessor
func (*ImageMetadataPreprocessor) CanProcess ¶
func (imp *ImageMetadataPreprocessor) CanProcess(filePath string) bool
CanProcess checks if this preprocessor can handle the given file
func (*ImageMetadataPreprocessor) GetName ¶
func (imp *ImageMetadataPreprocessor) GetName() string
GetName returns the name of this preprocessor
func (*ImageMetadataPreprocessor) GetSupportedExtensions ¶
func (imp *ImageMetadataPreprocessor) GetSupportedExtensions() []string
GetSupportedExtensions returns the file extensions this preprocessor supports
func (*ImageMetadataPreprocessor) Process ¶
func (imp *ImageMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
Process extracts metadata from image files
func (*ImageMetadataPreprocessor) SetObserver ¶
func (imp *ImageMetadataPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
type MediaProcessingError ¶
type MediaProcessingError struct {
FilePath string
FileType string
ErrorType ErrorType
Message string
Cause error
Recoverable bool
Context map[string]interface{}
}
MediaProcessingError represents a comprehensive error during media processing
func NewMediaProcessingError ¶
func NewMediaProcessingError(filePath, fileType string, errorType ErrorType, message string, cause error) *MediaProcessingError
NewMediaProcessingError creates a new media processing error
func (*MediaProcessingError) Error ¶
func (mpe *MediaProcessingError) Error() string
Error implements the error interface
func (*MediaProcessingError) GetContext ¶
func (mpe *MediaProcessingError) GetContext() map[string]interface{}
GetContext returns the error context
func (*MediaProcessingError) GetErrorType ¶
func (mpe *MediaProcessingError) GetErrorType() ErrorType
GetErrorType returns the error type
func (*MediaProcessingError) IsRecoverable ¶
func (mpe *MediaProcessingError) IsRecoverable() bool
IsRecoverable returns whether the error is recoverable
func (*MediaProcessingError) Unwrap ¶
func (mpe *MediaProcessingError) Unwrap() error
Unwrap returns the underlying error
func (*MediaProcessingError) WithContext ¶
func (mpe *MediaProcessingError) WithContext(key string, value interface{}) *MediaProcessingError
WithContext adds context to the error
type MediaResourceManager ¶
type MediaResourceManager struct {
// contains filtered or unexported fields
}
MediaResourceManager manages resource limits for media file processing
func NewMediaResourceManager ¶
func NewMediaResourceManager() *MediaResourceManager
NewMediaResourceManager creates a new resource manager with default limits
func NewMediaResourceManagerWithLimits ¶
func NewMediaResourceManagerWithLimits(limits *ResourceLimits) *MediaResourceManager
NewMediaResourceManagerWithLimits creates a new resource manager with custom limits
func (*MediaResourceManager) CreateProcessingContext ¶
func (rm *MediaResourceManager) CreateProcessingContext() (context.Context, context.CancelFunc)
CreateProcessingContext creates a context with timeout for processing
func (*MediaResourceManager) GetLimits ¶
func (rm *MediaResourceManager) GetLimits() *ResourceLimits
GetLimits returns the current resource limits
func (*MediaResourceManager) SetLimits ¶
func (rm *MediaResourceManager) SetLimits(limits *ResourceLimits)
SetLimits updates the resource limits
func (*MediaResourceManager) ValidateFileSize ¶
func (rm *MediaResourceManager) ValidateFileSize(filePath string, isVideo bool) error
ValidateFileSize checks if the file size is within limits
type MetadataFormatter ¶
type MetadataFormatter struct{}
MetadataFormatter provides common metadata formatting functions
func NewMetadataFormatter ¶
func NewMetadataFormatter() *MetadataFormatter
NewMetadataFormatter creates a new metadata formatter
func (*MetadataFormatter) CalculateTextMetrics ¶
func (mf *MetadataFormatter) CalculateTextMetrics(text string) (wordCount, charCount, lineCount int)
CalculateTextMetrics calculates word count, character count, and line count for text
func (*MetadataFormatter) FormatBooleanField ¶
func (mf *MetadataFormatter) FormatBooleanField(key string, value bool) string
FormatBooleanField formats a boolean field, only including it if true
func (*MetadataFormatter) FormatDateField ¶
func (mf *MetadataFormatter) FormatDateField(key string, date time.Time) string
FormatDateField formats a date field with consistent formatting
func (*MetadataFormatter) FormatMetadataField ¶
func (mf *MetadataFormatter) FormatMetadataField(key, value string) string
FormatMetadataField formats a metadata field with proper key-value formatting
func (*MetadataFormatter) FormatNumericField ¶
func (mf *MetadataFormatter) FormatNumericField(key string, value int) string
FormatNumericField formats a numeric field, only including it if greater than zero
func (*MetadataFormatter) FormatPropertiesMap ¶
func (mf *MetadataFormatter) FormatPropertiesMap(properties map[string]string, excludeKeys []string) string
FormatPropertiesMap formats a map of additional properties
type MetadataProcessingConfig ¶
type MetadataProcessingConfig struct {
EnableRetry bool
MaxRetries int
EnableResourceLimits bool
EnableObservability bool
}
MetadataProcessingConfig holds configuration for metadata processing
func DefaultMetadataProcessingConfig ¶
func DefaultMetadataProcessingConfig() *MetadataProcessingConfig
DefaultMetadataProcessingConfig returns default configuration
type OfficeMetadataPreprocessor ¶
type OfficeMetadataPreprocessor struct {
*BaseMetadataPreprocessor
}
OfficeMetadataPreprocessor extracts metadata from Office documents
func NewOfficeMetadataPreprocessor ¶
func NewOfficeMetadataPreprocessor() *OfficeMetadataPreprocessor
NewOfficeMetadataPreprocessor creates a new Office metadata preprocessor
func (*OfficeMetadataPreprocessor) CanProcess ¶
func (omp *OfficeMetadataPreprocessor) CanProcess(filePath string) bool
CanProcess checks if this preprocessor can handle the given file
func (*OfficeMetadataPreprocessor) GetSupportedExtensions ¶
func (omp *OfficeMetadataPreprocessor) GetSupportedExtensions() []string
GetSupportedExtensions returns the file extensions this preprocessor supports
func (*OfficeMetadataPreprocessor) Process ¶
func (omp *OfficeMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
Process extracts metadata from Office documents
func (*OfficeMetadataPreprocessor) SetObserver ¶
func (omp *OfficeMetadataPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
func (*OfficeMetadataPreprocessor) SetRouter ¶
func (omp *OfficeMetadataPreprocessor) SetRouter(router RouterInterface)
SetRouter sets the router instance for reprocessing embedded media
type PDFMetadataPreprocessor ¶
type PDFMetadataPreprocessor struct {
*BaseMetadataPreprocessor
}
PDFMetadataPreprocessor extracts metadata from PDF documents
func NewPDFMetadataPreprocessor ¶
func NewPDFMetadataPreprocessor() *PDFMetadataPreprocessor
NewPDFMetadataPreprocessor creates a new PDF metadata preprocessor
func (*PDFMetadataPreprocessor) CanProcess ¶
func (pmp *PDFMetadataPreprocessor) CanProcess(filePath string) bool
CanProcess checks if this preprocessor can handle the given file
func (*PDFMetadataPreprocessor) GetSupportedExtensions ¶
func (pmp *PDFMetadataPreprocessor) GetSupportedExtensions() []string
GetSupportedExtensions returns the file extensions this preprocessor supports
func (*PDFMetadataPreprocessor) Process ¶
func (pmp *PDFMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
Process extracts metadata from the PDF file
func (*PDFMetadataPreprocessor) SetObserver ¶
func (pmp *PDFMetadataPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
func (*PDFMetadataPreprocessor) SetRouter ¶
func (pmp *PDFMetadataPreprocessor) SetRouter(router RouterInterface)
SetRouter sets the router instance for reprocessing embedded media
type PlainTextPreprocessor ¶
type PlainTextPreprocessor struct {
// contains filtered or unexported fields
}
PlainTextPreprocessor handles plain text files by passing their content through This ensures text files are processed through the same pipeline as other file types
func NewPlainTextPreprocessor ¶
func NewPlainTextPreprocessor() *PlainTextPreprocessor
NewPlainTextPreprocessor creates a new plain text preprocessor
func NewPlainTextPreprocessorWithConfig ¶
func NewPlainTextPreprocessorWithConfig(enableRedaction bool) *PlainTextPreprocessor
NewPlainTextPreprocessorWithConfig creates a new plain text preprocessor with redaction configuration
func (*PlainTextPreprocessor) CanProcess ¶
func (ptp *PlainTextPreprocessor) CanProcess(filePath string) bool
CanProcess checks if this preprocessor can handle the given file
func (*PlainTextPreprocessor) GetName ¶
func (ptp *PlainTextPreprocessor) GetName() string
GetName returns the name of this preprocessor
func (*PlainTextPreprocessor) GetSupportedExtensions ¶
func (ptp *PlainTextPreprocessor) GetSupportedExtensions() []string
GetSupportedExtensions returns the file extensions this preprocessor supports
func (*PlainTextPreprocessor) Process ¶
func (ptp *PlainTextPreprocessor) Process(filePath string) (*ProcessedContent, error)
Process extracts text content from the file
func (*PlainTextPreprocessor) SetObserver ¶
func (ptp *PlainTextPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
type PositionMapping ¶
type PositionMapping struct {
// ExtractedPosition is the position in the extracted text
ExtractedPosition TextPosition `json:"extracted_position"`
// OriginalPosition is the corresponding position in the original document
OriginalPosition DocumentPosition `json:"original_position"`
// ConfidenceScore is the confidence in this position mapping (0.0 to 1.0)
ConfidenceScore float64 `json:"confidence_score"`
// Context is surrounding text for verification
Context string `json:"context,omitempty"`
// Method describes how this mapping was determined
Method string `json:"method"`
}
PositionMapping represents a mapping between extracted text positions and original document positions
type Preprocessor ¶
type Preprocessor interface {
// CanProcess checks if this preprocessor can handle the given file
CanProcess(filePath string) bool
// Process extracts content from the file
Process(filePath string) (*ProcessedContent, error)
// GetName returns the name of this preprocessor
GetName() string
// GetSupportedExtensions returns the file extensions this preprocessor supports
GetSupportedExtensions() []string
// SetObserver sets the observability component
SetObserver(observer observability.Observer)
}
Preprocessor interface defines methods for preprocessing files
type PreprocessorManager ¶
type PreprocessorManager struct {
// contains filtered or unexported fields
}
PreprocessorManager manages all available preprocessors
func NewPreprocessorManager ¶
func NewPreprocessorManager() *PreprocessorManager
NewPreprocessorManager creates a new preprocessor manager
func (*PreprocessorManager) GetAvailablePreprocessors ¶
func (pm *PreprocessorManager) GetAvailablePreprocessors() []Preprocessor
GetAvailablePreprocessors returns all registered preprocessors
func (*PreprocessorManager) GetPreprocessor ¶
func (pm *PreprocessorManager) GetPreprocessor(filePath string) Preprocessor
GetPreprocessor returns the appropriate preprocessor for a file, or nil if none found
func (*PreprocessorManager) ProcessFile ¶
func (pm *PreprocessorManager) ProcessFile(filePath string) (*ProcessedContent, error)
ProcessFile processes a file with all appropriate preprocessors
func (*PreprocessorManager) RegisterPreprocessor ¶
func (pm *PreprocessorManager) RegisterPreprocessor(p Preprocessor)
RegisterPreprocessor adds a preprocessor to the manager
type ProcessedContent ¶
type ProcessedContent struct {
// Original file information
OriginalPath string
Filename string
// Extracted content
Text string
// Content metadata
Format string
PageCount int
WordCount int
CharCount int
LineCount int
Paragraphs int
// Processing information
ProcessorType string
Success bool
Error error
// ExtractionWarning is a short, payload-free note that extraction SUCCEEDED
// but produced suspiciously nothing — e.g. a container whose format carries a
// document body yielded no body text. It is deliberately not an Error: the
// file was read and whatever was extracted is valid, so the scan continues and
// the findings stand. It exists because "extracted nothing" and "the document
// is empty" used to be indistinguishable — both were Success with textLen 0 —
// which made a skipped document body look like a clean scan.
ExtractionWarning string
// Position mapping information for redaction
PositionMappings []PositionMapping `json:"position_mappings,omitempty"`
// Position tracking metadata
PositionTrackingEnabled bool `json:"position_tracking_enabled"`
PositionConfidence float64 `json:"position_confidence"`
PositionMetadata map[string]interface{} `json:"position_metadata,omitempty"`
// Additional metadata for embedded media and other extensions
Metadata map[string]interface{}
// Sections carries the structure of Text OUT OF BAND: one entry per
// preprocessor whose output was concatenated into Text, in the same order.
//
// It exists because the structure used to be carried IN BAND. The file router
// flattens every extractor's output into Text with literal "\n\n--- name ---\n"
// separators, and the content router then re-parsed that text to recover which
// bytes came from which extractor. Document authors control the text, so they
// controlled the recovered "structure": a paragraph typed as
// "--- office_metadata ---" became a section boundary. That is in-band
// signalling, the same class of defect as SQL injection, and it has the same
// answer — carry the structure alongside the data instead of re-deriving it
// from the data.
//
// Text stays the flat concatenation, byte for byte, so every existing consumer
// is unaffected; this field is purely additive. A nil/empty Sections means "no
// structure was declared", which consumers must treat as "all of Text is
// document body" — the safe direction, since the document path runs the full
// validator set and the metadata path runs one field-name scanner.
Sections []ContentSection
}
ProcessedContent represents content that has been processed by a preprocessor
func (*ProcessedContent) AddPositionMapping ¶
func (pc *ProcessedContent) AddPositionMapping(mapping PositionMapping)
AddPositionMapping adds a position mapping to the processed content
func (*ProcessedContent) AddPositionMetadata ¶
func (pc *ProcessedContent) AddPositionMetadata(key string, value interface{})
AddPositionMetadata adds metadata related to position tracking
func (*ProcessedContent) EnablePositionTracking ¶
func (pc *ProcessedContent) EnablePositionTracking()
EnablePositionTracking enables position tracking for this content
func (*ProcessedContent) GetPositionMappingsForRange ¶
func (pc *ProcessedContent) GetPositionMappingsForRange(startLine, startChar, endLine, endChar int) []PositionMapping
GetPositionMappingsForRange returns position mappings that overlap with the given text range
func (*ProcessedContent) SetPositionConfidence ¶
func (pc *ProcessedContent) SetPositionConfidence(confidence float64)
SetPositionConfidence sets the overall confidence for position mappings
type ProcessedContentBuilder ¶
type ProcessedContentBuilder struct {
// contains filtered or unexported fields
}
ProcessedContentBuilder helps build ProcessedContent structures consistently
func NewProcessedContentBuilder ¶
func NewProcessedContentBuilder() *ProcessedContentBuilder
NewProcessedContentBuilder creates a new processed content builder
func (*ProcessedContentBuilder) BuildErrorContent ¶
func (pcb *ProcessedContentBuilder) BuildErrorContent(filePath, format, processorType string, err error) *ProcessedContent
BuildErrorContent creates a failed ProcessedContent structure
func (*ProcessedContentBuilder) BuildSuccessContent ¶
func (pcb *ProcessedContentBuilder) BuildSuccessContent(filePath, text, format, processorType string, pageCount int) *ProcessedContent
BuildSuccessContent creates a successful ProcessedContent structure
type ProcessingError ¶
ProcessingError represents an error that occurred during media processing
func NewProcessingError ¶
func NewProcessingError(filePath, fileType, reason string, err error) *ProcessingError
NewProcessingError creates a new processing error
func (*ProcessingError) Error ¶
func (pe *ProcessingError) Error() string
Error implements the error interface
func (*ProcessingError) Unwrap ¶
func (pe *ProcessingError) Unwrap() error
Unwrap returns the underlying error
type RecoveryStrategy ¶
type RecoveryStrategy int
RecoveryStrategy represents different recovery strategies
const ( RecoveryStrategyNone RecoveryStrategy = iota RecoveryStrategyRetry RecoveryStrategyFallback RecoveryStrategySkip )
type ResourceLimits ¶
type ResourceLimits struct {
MaxVideoFileSize int64 // Maximum video file size in bytes
MaxAudioFileSize int64 // Maximum audio file size in bytes
ProcessingTimeout time.Duration // Maximum processing time per file
MaxMemoryUsage int64 // Maximum memory usage per file
}
ResourceLimits defines limits for media file processing
func DefaultResourceLimits ¶
func DefaultResourceLimits() *ResourceLimits
DefaultResourceLimits returns the default resource limits for media processing
type RouterIntegrationHelper ¶
type RouterIntegrationHelper struct{}
RouterIntegrationHelper provides utilities for router integration
func NewRouterIntegrationHelper ¶
func NewRouterIntegrationHelper() *RouterIntegrationHelper
NewRouterIntegrationHelper creates a new router integration helper
func (*RouterIntegrationHelper) CreateEmbeddedMediaPath ¶
func (rih *RouterIntegrationHelper) CreateEmbeddedMediaPath(originalFilePath, embeddedFileName string) string
CreateEmbeddedMediaPath creates a path showing the relationship between original file and embedded media
func (*RouterIntegrationHelper) FormatEmbeddedMediaSection ¶
func (rih *RouterIntegrationHelper) FormatEmbeddedMediaSection(index int, mediaName, content string) string
FormatEmbeddedMediaSection formats embedded media content for inclusion in metadata text.
The "--- Embedded Media N (name) ---" line is now DISPLAY ONLY: it tells a human reading the extracted text where an embedded item begins, and nothing parses it back. Two readers used to, and both let a document author choose the reported source of a finding just by typing this line as body text — the content router's extractEmbeddedMediaPath (deleted with the rest of the text-sniffing read side) and the METADATA validator's line loop. The real provenance travels out of band in ContentSection.SourceFile, set by the preprocessor that actually opened the archive member.
So do not reintroduce a parser for this text, and do not "fix" a wrong attribution by escaping the parentheses or the name: an author still controls whatever a parser would read, and the structure carries the answer already.
type RouterInterface ¶
type RouterInterface interface {
ProcessFile(filePath string, context interface{}) (*ProcessedContent, error)
// ProcessEmbedded processes a child file that was extracted OUT OF parentPath,
// enforcing a nesting-depth bound.
//
// Separate from ProcessFile because the router is the only component that can own
// the depth: the preprocessor instance is shared across concurrent workers (so it
// cannot hold per-call state) and Process takes no context to thread one through.
// The preprocessor knows its own path — that is the argument to Process — so
// passing it as parentPath is enough for the router to compute depth without any
// change to the Preprocessor interface.
//
// Returns ErrEmbeddedTooDeep when the bound is reached. Callers must DISCLOSE
// that rather than skipping quietly: refusing to descend is incomplete coverage,
// and an undisclosed gap reads as a clean result.
ProcessEmbedded(childPath, parentPath string) (*ProcessedContent, error)
// CanProcessFile reports whether the router can process a file at all, and why
// not when it cannot.
//
// Needed so embedded parts are admitted by CAPABILITY rather than by a private
// extension list. The list version excluded 19% of the embedded parts in a real
// corpus, including .svg, which scans perfectly well as a standalone file. Asking
// the router means a preprocessor added anywhere -- including the byte-sniffing
// text fallback -- extends embedded coverage for free instead of leaving a
// second list to maintain.
CanProcessFile(filePath string, enablePreprocessors bool) (bool, string)
}
RouterInterface defines the router functionality the metadata preprocessors need (set via SetRouter). Defined here alongside its only consumer, BaseMetadataPreprocessor and the specialized preprocessors that embed it.
type SectionKind ¶ added in v2.2.1
type SectionKind int
SectionKind is the routing classification of a ContentSection.
const ( // SectionKindBody is document body text: the full validator set applies. SectionKindBody SectionKind = iota // SectionKindMetadata is extracted metadata fields: the METADATA validator's // per-preprocessor field rules apply. Note this is about LABELLING, not // coverage — the document path scans the union of all sections regardless. SectionKindMetadata )
func ClassifySection ¶ added in v2.2.1
func ClassifySection(preprocessorName string) (SectionKind, string)
ClassifySection maps a preprocessor's GetName() to a section Kind and metadata Type. It lives next to the metadata_constants.go names it matches, and it is a CLOSED switch on the seven names this repo's preprocessors actually return (verified against every GetName() implementation) rather than a substring search.
A closed switch is the security-relevant part. The name it classifies is our own code's constant, so an exact match is always possible; substring matching was how the old text-parsing path turned a document paragraph named "--- Employee Metadata ---" into a metadata section. Anything unrecognized classifies as BODY, which is the fail-closed direction: the document path runs the full validator set, so a preprocessor added later without updating this switch loses a label, not coverage.
type SharedUtilities ¶
type SharedUtilities struct {
}
SharedUtilities provides a centralized access point for all shared utilities
func NewSharedUtilities ¶
func NewSharedUtilities() *SharedUtilities
NewSharedUtilities creates a new shared utilities instance
type TextEncoding ¶ added in v2.1.2
type TextEncoding int
TextEncoding identifies the on-disk encoding of a text file, as detected from its leading bytes. Only encodings ferret-scan can transparently decode to UTF-8 (and re-encode on the redaction write path) are enumerated; everything else is EncodingUnknown and handled by the legacy byte-level heuristics.
const ( // EncodingUTF8 is plain UTF-8 / ASCII — no transform needed. EncodingUTF8 TextEncoding = iota // EncodingUTF8BOM is UTF-8 with a leading BOM (Windows Notepad default). // The BOM is stripped on decode and restored on encode. EncodingUTF8BOM // EncodingUTF16LE is UTF-16 little-endian with BOM (PowerShell 5 // Out-File default, regedit .reg exports, many Windows logs). EncodingUTF16LE // EncodingUTF16BE is UTF-16 big-endian with BOM. EncodingUTF16BE // EncodingUTF16LENoBOM is BOM-less UTF-16 LE, detected by the // alternating-null heuristic. EncodingUTF16LENoBOM // EncodingUTF16BENoBOM is BOM-less UTF-16 BE. EncodingUTF16BENoBOM // EncodingUnknown means "not a transcodable encoding we recognize" — // callers fall back to treating the bytes as-is. EncodingUnknown )
func DetectTextEncoding ¶ added in v2.1.2
func DetectTextEncoding(buf []byte) TextEncoding
DetectTextEncoding inspects the leading bytes of buf (any prefix of the file, e.g. the 512-byte sniff window or the whole content) and identifies the encoding. Detection order matters: BOMs are unambiguous and checked first; the BOM-less UTF-16 heuristic runs only when the buffer contains null bytes in the tell-tale alternating pattern (UTF-16-encoded ASCII/Latin text has a 0x00 in every other byte, which is exactly why the legacy null-byte check classified such files as binary).
func (TextEncoding) String ¶ added in v2.1.2
func (e TextEncoding) String() string
String returns a short name for metadata/debug surfaces.
type TextPosition ¶
type TextPosition struct {
// Line is the line number (1-based)
Line int `json:"line"`
// StartChar is the starting character position in the line (0-based)
StartChar int `json:"start_char"`
// EndChar is the ending character position in the line (0-based)
EndChar int `json:"end_char"`
// AbsoluteOffset is the absolute character offset from the beginning of the text
AbsoluteOffset int `json:"absolute_offset"`
}
TextPosition represents a position in extracted text
type TextPreprocessor ¶
type TextPreprocessor struct {
// contains filtered or unexported fields
}
TextPreprocessor handles text extraction from various document formats
func NewTextPreprocessor ¶
func NewTextPreprocessor() *TextPreprocessor
NewTextPreprocessor creates a new text preprocessor
func (*TextPreprocessor) CanProcess ¶
func (tp *TextPreprocessor) CanProcess(filePath string) bool
CanProcess checks if this preprocessor can handle the given file
func (*TextPreprocessor) GetName ¶
func (tp *TextPreprocessor) GetName() string
GetName returns the name of this preprocessor
func (*TextPreprocessor) GetSupportedExtensions ¶
func (tp *TextPreprocessor) GetSupportedExtensions() []string
GetSupportedExtensions returns the file extensions this preprocessor supports
func (*TextPreprocessor) Process ¶
func (tp *TextPreprocessor) Process(filePath string) (*ProcessedContent, error)
Process extracts text content from the file
func (*TextPreprocessor) SetObserver ¶
func (tp *TextPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
type VideoMetadataPreprocessor ¶
type VideoMetadataPreprocessor struct {
*BaseMetadataPreprocessor
}
VideoMetadataPreprocessor extracts metadata from video files
func NewVideoMetadataPreprocessor ¶
func NewVideoMetadataPreprocessor() *VideoMetadataPreprocessor
NewVideoMetadataPreprocessor creates a new video metadata preprocessor
func (*VideoMetadataPreprocessor) CanProcess ¶
func (vmp *VideoMetadataPreprocessor) CanProcess(filePath string) bool
CanProcess checks if this preprocessor can handle the given file
func (*VideoMetadataPreprocessor) GetSupportedExtensions ¶
func (vmp *VideoMetadataPreprocessor) GetSupportedExtensions() []string
GetSupportedExtensions returns the file extensions this preprocessor supports
func (*VideoMetadataPreprocessor) Process ¶
func (vmp *VideoMetadataPreprocessor) Process(filePath string) (*ProcessedContent, error)
Process extracts metadata from video files with comprehensive error handling and retry logic
func (*VideoMetadataPreprocessor) SetObserver ¶
func (vmp *VideoMetadataPreprocessor) SetObserver(observer observability.Observer)
SetObserver sets the observability component
func (*VideoMetadataPreprocessor) SetRouter ¶
func (vmp *VideoMetadataPreprocessor) SetRouter(router RouterInterface)
SetRouter sets the router instance (not used for video metadata but required by interface)
Source Files
¶
- audio_metadata_preprocessor.go
- base_metadata_preprocessor.go
- encoding.go
- error_handling.go
- image_metadata_preprocessor.go
- metadata_constants.go
- office_metadata_preprocessor.go
- pdf_metadata_preprocessor.go
- plaintext_preprocessor.go
- preprocessor.go
- resource_limits.go
- shared_utilities.go
- text_preprocessor.go
- video_metadata_preprocessor.go