package worker import ( "context" "io/fs" "mime" "path/filepath" "git.sr.ht/~gabrielgio/img/pkg/database/repository" "git.sr.ht/~gabrielgio/img/pkg/fileop" ) type ( FileScanner struct { root string repository repository.MediaRepository } ) var _ ChanProcessor[string] = &FileScanner{} func NewFileScanner(root string, repository repository.MediaRepository) *FileScanner { return &FileScanner{ root: root, repository: repository, } } func (f *FileScanner) Query(ctx context.Context) (<-chan string, error) { c := make(chan string) go func() { defer close(c) _ = filepath.Walk(f.root, func(path string, info fs.FileInfo, err error) error { select { case <-ctx.Done(): return filepath.SkipAll default: } if info == nil { return nil } if info.IsDir() && filepath.Base(info.Name())[0] == '.' { return filepath.SkipDir } if info.IsDir() { return nil } c <- path return nil }) }() return c, nil } func (f *FileScanner) Process(ctx context.Context, path string) error { mimetype := mime.TypeByExtension(filepath.Ext(path)) supported := fileop.IsMimeTypeSupported(mimetype) if !supported { return nil } hash := fileop.GetHashFromPath(path) exists, err := f.repository.Exists(ctx, hash) if err != nil { return err } if exists { return nil } return f.repository.Create(ctx, &repository.CreateMedia{ Name: filepath.Base(path), Path: path, PathHash: hash, MIMEType: mimetype, }) }