Files
silo-server/internal/scanner/root_observation.go
T

102 lines
3.0 KiB
Go

package scanner
import (
"path/filepath"
"github.com/Silo-Server/silo-server/internal/models"
"github.com/Silo-Server/silo-server/internal/naming"
)
const (
RootObservationReasonMatchable = "matchable"
RootObservationReasonMissingFolderIDs = "missing_folder_ids"
)
// RootObservation summarizes one scanned content root and whether it is
// eligible for scanner-driven matching.
type RootObservation struct {
RootPath string
SampleFilePath string
FileCount int
HasFolderIDs bool
Reason string
}
type fileRootAssignment = naming.RootAssignment
type rootInferenceResult struct {
Observations []RootObservation
Snapshots []models.ScannedMediaRoot
Assignments map[string]fileRootAssignment
}
// ObserveRoot derives the logical content root for a media file path.
func ObserveRoot(filePath string, libraryType string) (RootObservation, bool) {
result := inferRootAssignments([]string{filePath}, libraryType, 0, nil)
assignment, ok := result.Assignments[filepath.Clean(filePath)]
if !ok {
return RootObservation{}, false
}
return observationFromAssignment(assignment), true
}
func collectRootObservations(filePaths []string, libraryType string) []RootObservation {
return inferRootAssignments(filePaths, libraryType, 0, nil).Observations
}
func collectScannedRoots(
filePaths []string,
libraryType string,
folderID int,
overrides map[string]models.MediaRootOverride,
) []models.ScannedMediaRoot {
return inferRootAssignments(filePaths, libraryType, folderID, overrides).Snapshots
}
func inferRootAssignments(
filePaths []string,
libraryType string,
folderID int,
overrides map[string]models.MediaRootOverride,
) rootInferenceResult {
snapshots, assignments := naming.InferRootAssignments(filePaths, libraryType, folderID, overrides)
observations := make([]RootObservation, 0, len(snapshots))
for _, snapshot := range snapshots {
observations = append(observations, observationFromSnapshot(snapshot))
}
return rootInferenceResult{
Observations: observations,
Snapshots: snapshots,
Assignments: assignments,
}
}
func observationFromAssignment(assignment fileRootAssignment) RootObservation {
observation := RootObservation{
RootPath: assignment.RootPath,
SampleFilePath: assignment.FilePath,
FileCount: 1,
HasFolderIDs: assignment.HasFolderIDs,
Reason: RootObservationReasonMissingFolderIDs,
}
if assignment.HasFolderIDs {
observation.Reason = RootObservationReasonMatchable
}
return observation
}
func observationFromSnapshot(snapshot models.ScannedMediaRoot) RootObservation {
hasFolderIDs := naming.ParseFolderIDs(filepath.Base(snapshot.RootPath), snapshot.InferredType) != nil
observation := RootObservation{
RootPath: snapshot.RootPath,
SampleFilePath: snapshot.SampleFilePath,
FileCount: snapshot.ObservedFileCount,
HasFolderIDs: hasFolderIDs,
Reason: RootObservationReasonMissingFolderIDs,
}
if hasFolderIDs {
observation.Reason = RootObservationReasonMatchable
}
return observation
}