Documentation
¶
Overview ¶
Package engine contains the core processing logic for revoco. This file implements Phase 1: file discovery and JSON-to-media matching.
Index ¶
- func ApplyEXIFBatch(ctx context.Context, destMap map[string]string, mediaJSON map[string]string, ...) (applied, dateFallback, skipped, errCount int, errs []error, fatalErr error)
- func ConvertMotionPhotos(destMap map[string]string, dryRun bool, logger *log.Logger, ...) (converted int, errs []error)
- func FormatDate(unix int64) string
- func FormatTimestamp(unix int64) string
- func ParseUnixString(s string) int64
- type AlbumsResult
- type AnalysisResult
- type ExifTool
- type HashResult
- type IndexResult
- type MissingReport
- type OrphanJSON
- type PipelineConfig
- type PipelineResult
- type ProgressEvent
- type RecoverConfig
- type RecoverEvent
- type RecoverResult
- type Stats
- type TransferConfig
- type TransferResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ApplyEXIFBatch ¶
func ApplyEXIFBatch( ctx context.Context, destMap map[string]string, mediaJSON map[string]string, dryRun bool, logger *log.Logger, progress func(done, total int), ) (applied, dateFallback, skipped, errCount int, errs []error, fatalErr error)
ApplyEXIFBatch applies metadata to a batch of files using the persistent exiftool process. For files with JSON: uses JSON metadata. For files without JSON: falls back to filename date. The context allows cancellation during the batch processing loop. Returns an error if exiftool is not available (fatal error).
func ConvertMotionPhotos ¶
func ConvertMotionPhotos(destMap map[string]string, dryRun bool, logger *log.Logger, progress func(done, total int)) (converted int, errs []error)
ConvertMotionPhotos finds .MP and .COVER files in destMap and converts them to .mp4 using ffmpeg (stream copy, no re-encode).
func FormatDate ¶
FormatDate formats a Unix timestamp as a date-only string.
func FormatTimestamp ¶
FormatTimestamp formats a Unix timestamp as "YYYY:MM:DD HH:MM:SS" for EXIF.
func ParseUnixString ¶
ParseUnixString parses a string Unix timestamp, returning 0 on error.
Types ¶
type AlbumsResult ¶
type AlbumsResult struct {
// MediaAlbum maps media path -> album name ("" = root / no album)
MediaAlbum map[string]string
NamedAlbums []string
}
AlbumsResult holds Phase 2 output: which album (if any) each media file belongs to.
func AssignAlbums ¶
func AssignAlbums(gfotoPath string, mediaFiles map[string]string) (*AlbumsResult, error)
AssignAlbums classifies Takeout subfolders and assigns album membership to each media file.
type AnalysisResult ¶
type AnalysisResult struct {
TotalMedia int
TotalJSON int
MatchRate float64 // 0.0–1.0
TotalBytes int64
Albums []string
EarliestDate time.Time
LatestDate time.Time
MotionPhotos int
Videos int
}
AnalysisResult is returned by Analyze and shown on the pre-flight screen.
func Analyze ¶
func Analyze(sourceDir string, progress func(done, total int)) (*AnalysisResult, error)
Analyze performs a quick (read-only) scan of a Takeout source directory and returns statistics for the pre-flight screen. It accepts an optional progress callback that is called with (done, total) file counts as the walk proceeds.
type ExifTool ¶
type ExifTool struct {
// contains filtered or unexported fields
}
ExifTool manages a persistent exiftool -stay_open process to avoid per-file process spawn overhead.
func NewExifTool ¶
NewExifTool starts a persistent exiftool process. The logger is used to capture stderr output from exiftool.
func (*ExifTool) ApplyDateFromFilename ¶
ApplyDateFromFilename extracts a date from the filename and applies it via exiftool.
func (*ExifTool) ApplyEXIFFromJSON ¶
ApplyEXIFFromJSON applies metadata from a Takeout JSON file to its media file.
type HashResult ¶
type HashResult struct {
// MediaHash maps media path -> hex MD5 hash
MediaHash map[string]string
// Unique is the deduplicated set of media paths to keep (album copies win)
Unique []string
// Duplicates is the count of removed duplicate files
Duplicates int
}
HashResult holds Phase 3 deduplication output.
func DeduplicateFiles ¶
func DeduplicateFiles(mediaFiles map[string]string, mediaAlbum map[string]string, progress func(done, total int)) (*HashResult, error)
DeduplicateFiles computes MD5 hashes for all media files and removes duplicates. Album files (mediaAlbum[path] != "") take priority over root files.
type IndexResult ¶
type IndexResult struct {
// MediaFiles maps media path -> its matched JSON path (empty if unmatched)
MediaFiles map[string]string
// OrphanJSONs are JSON files with no matching media
OrphanJSONs []OrphanJSON
// Stats
TotalMedia int
TotalJSON int
TotalMatched int
TotalOrphans int
}
IndexResult holds the output of Phase 1.
func IndexFiles ¶
func IndexFiles(ctx context.Context, gfotoPath string, progress func(done, total int)) (*IndexResult, error)
IndexFiles walks the Google Photos subdirectory, classifies all files, and matches JSON metadata to their corresponding media files. The context allows cancellation during the matching phase.
type MissingReport ¶
type MissingReport struct {
Entries []metadata.MissingEntry
Path string
}
MissingReport is the output of Phase 8.
func GenerateReport ¶
func GenerateReport(orphans []OrphanJSON, destDir string) (*MissingReport, error)
GenerateReport builds missing-files.json from orphan JSON entries and writes it to destDir.
type OrphanJSON ¶
type OrphanJSON struct {
Path string
Title string
URL string
PhotoTakenTS int64
CreationTS int64
SourceFolder string
}
OrphanJSON is a JSON metadata file with no corresponding media file.
type PipelineConfig ¶
type PipelineConfig struct {
SourceDir string
DestDir string
SessionDir string // if set, logs go here instead of DestDir
UseMove bool
DryRun bool
}
PipelineConfig holds all options for a full processing run.
type PipelineResult ¶
type PipelineResult struct {
Stats Stats
Report *MissingReport
LogPath string
}
PipelineResult is the final output of a complete run.
func Run ¶
func Run(cfg PipelineConfig, events chan<- ProgressEvent) (*PipelineResult, error)
Run executes the full 8-phase pipeline, emitting progress events on the provided channel. The channel is closed when the run completes. This is a convenience wrapper around RunWithContext using context.Background().
func RunWithContext ¶
func RunWithContext(ctx context.Context, cfg PipelineConfig, events chan<- ProgressEvent) (*PipelineResult, error)
RunWithContext executes the full 8-phase pipeline with cancellation support. The channel is closed when the run completes or is cancelled.
type ProgressEvent ¶
type ProgressEvent struct {
Phase int
Label string
Done int
Total int
Message string // optional log message
}
ProgressEvent is emitted by the pipeline to report progress to the TUI/CLI.
type RecoverConfig ¶
type RecoverConfig struct {
// InputJSON is the path to missing-files.json produced by Phase 8.
InputJSON string
// OutputDir is where recovered files are placed.
OutputDir string
// SessionDir, if set, is where logs are written (instead of OutputDir).
SessionDir string
// CookieJar is the path to the Netscape cookie jar file.
CookieJar string
// Concurrency is the number of parallel downloads.
Concurrency int
// Delay is the minimum pause between requests (per worker) in seconds.
Delay float64
// MaxRetry is the maximum number of attempts per file.
MaxRetry int
// StartFrom is the 1-indexed entry to resume from.
StartFrom int
// DryRun reports what would be downloaded without doing it.
DryRun bool
}
RecoverConfig holds all options for a recovery run.
type RecoverEvent ¶
RecoverEvent is emitted during a recovery run.
type RecoverResult ¶
RecoverResult is the final summary of a recovery run.
func RunRecover ¶
func RunRecover(cfg RecoverConfig, events chan<- RecoverEvent) (*RecoverResult, error)
RunRecover executes the recovery pipeline. The events channel is closed when the run completes.
type Stats ¶
type Stats struct {
MediaFound int
JSONMatched int
JSONOrphans int
DuplicatesRemoved int
FilesTransferred int
ConflictsResolved int
MPConverted int
EXIFApplied int
DateFromFilename int
Errors int
Albums int
}
Stats is the final summary of a processing run.
type TransferConfig ¶
TransferConfig holds options for Phase 4.
type TransferResult ¶
type TransferResult struct {
// DestMap maps source media path -> destination path
DestMap map[string]string
FilesTransferred int
ConflictsResolved int
Errors int
ErrorList []error
}
TransferResult holds Phase 4 output.
func TransferFiles ¶
func TransferFiles( ctx context.Context, unique []string, mediaAlbum map[string]string, mediaJSON map[string]string, mediaHash map[string]string, cfg TransferConfig, logger *log.Logger, progress func(done, total int), ) (*TransferResult, error)
TransferFiles copies (or moves) deduplicated media files to the destination, preserving album subdirectory structure and resolving name conflicts. The context allows cancellation during the transfer loop.