102 lines
3.0 KiB
Go
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
|
|
}
|