package convids import ( "context" "errors" "fmt" "io" "os" "os/exec" fp "path/filepath" "regexp" "strings" "gopkg.in/yaml.v3" ) func NewData(path string) (*Data, error) { f, err := os.Open(path) if err != nil { return nil, err } ydec := yaml.NewDecoder(f) var data Data err = ydec.Decode(&data) return &data, err } func ensureExtRe(c *Config) (err error) { if c.extRe != nil { return nil } c.extRe, err = regexp.Compile("(" + strings.Join(c.Extensions, "|") + ")$") return } type ShowWalker func(show *Show, path string) error type GroupPrinter func(name string, group Shows) var ErrNoFiles = errors.New("no files processed") var ErrSkipped = errors.New("skipped") func processFile(conf *Config, walk ShowWalker, show *Show, file os.DirEntry) (processed bool, processError, cbError error) { if file.IsDir() { return } if !conf.extRe.MatchString(file.Name()) { return } var found bool found, processError = show.Match(file.Name()) if processError != nil || !found { return } path := fp.Join(conf.Source, file.Name()) for _, ext := range conf.Skip { if !strings.HasPrefix(ext, ".") { ext = "." + ext } skipper := path + ext _, statErr := os.Stat(skipper) if !errors.Is(statErr, os.ErrNotExist) { return processed, ErrSkipped, cbError } } cbError = walk(show, path) if cbError == nil { processed = true } return } func WalkFiles(d *Data, stopOnError bool, gp GroupPrinter, cb ShowWalker) (err error) { err = ensureExtRe(d.Config) if err != nil { return } if cb == nil { cb = DryRun(os.Stdout) } count := 0 var files []os.DirEntry files, err = os.ReadDir(d.Config.Source) if err != nil { return } for s := range d.AllShows(gp) { for _, file := range files { processed, processErr, cbErr := processFile(d.Config, cb, s, file) if !processed && processErr == nil && cbErr == nil { continue } if errors.Is(processErr, ErrSkipped) { continue } if processErr != nil { return processErr } if cbErr != nil && stopOnError { return cbErr } if cbErr == nil && processed { count++ } if cbErr != nil { err = cbErr } break } } if err == nil && count < 1 { fmt.Println("Found nothing") return ErrNoFiles } return } func DryRun(out io.Writer) ShowWalker { return func(s *Show, path string) error { fmt.Fprintf(out, "Saving %s to %s\n", path, s.Folder) return ErrSkipped } } func GetShow(ctx context.Context) ShowWalker { return func(s *Show, path string) error { cmd := exec.CommandContext(ctx, "get-shows", s.Folder, path) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() } } func PrintGroupName(out io.Writer) GroupPrinter { return func(name string, group Shows) { fmt.Fprintf(out, "Checking %s shows\n\n", name) } }