package main import ( "flag" "fmt" "os" "path/filepath" "regexp" "time" logger "git.site.quack-lab.dev/dave/cylogger" "git.site.quack-lab.dev/dave/cyutils" ) type DateParser interface { Parse(s string) (time.Time, error) } type DateParser8 struct { re *regexp.Regexp } func (dp *DateParser8) Parse(s string) (time.Time, error) { matches := dp.re.FindStringSubmatch(s) if len(matches) == 0 { return time.Time{}, fmt.Errorf("no match") } return time.Parse("20060102", matches[0]) } type DateParserISO struct { re *regexp.Regexp } func (dp *DateParserISO) Parse(s string) (time.Time, error) { matches := dp.re.FindStringSubmatch(s) if len(matches) == 0 { return time.Time{}, fmt.Errorf("no match") } return time.Parse("2006-01-02", matches[0]) } func main() { flag.Parse() logger.InitFlag() if flag.NArg() == 0 { logger.Error("no files provided") return } parsers := []DateParser{ &DateParser8{re: regexp.MustCompile(`\d{8}`)}, &DateParserISO{re: regexp.MustCompile(`\d{4}-\d{2}-\d{2}`)}, } files := flag.Args() cyutils.WithWorkers(10, files, func(worker int, _ int, file string) { workerlog := logger.Default.WithPrefix(fmt.Sprintf("worker=%d", worker)) filelog := workerlog.WithPrefix(fmt.Sprintf("file=%q", file)) filelog.Info("processing file") date, err := parseDate(file, parsers) if err != nil { filelog.Error("error parsing date: %s", err) return } filelog.Info("date: %s", date) datedir := fmt.Sprintf("%04d-%02d-%02d", date.Year(), date.Month(), date.Day()) dest := filepath.Join(datedir, file) filelog.Info("dest: %s", dest) err = os.MkdirAll(datedir, 0755) if err != nil { filelog.Error("error creating directory: %s", err) return } // Make sure file doesn't exist destfile, err := os.Stat(dest) if err == nil { filelog.Info("dest file already exists: %s", destfile.Name()) return } else { if !os.IsNotExist(err) { filelog.Error("error checking dest file: %s", err) return } } err = os.Rename(file, dest) if err != nil { filelog.Error("error renaming file: %s", err) return } filelog.Info("moved to %q", dest) }) } func parseDate(file string, parsers []DateParser) (time.Time, error) { for _, parser := range parsers { date, err := parser.Parse(file) if err == nil { return date, nil } } return time.Time{}, fmt.Errorf("no date found") }