131 lines
2.9 KiB
Go
131 lines
2.9 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"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()
|
|
// logger.Default = logger.Default.ToFile("dategrouper.log")
|
|
|
|
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)
|
|
|
|
dir := filepath.Dir(file)
|
|
datedir := filepath.Join(dir, fmt.Sprintf("%04d-%02d-%02d", date.Year(), date.Month(), date.Day()))
|
|
dest := filepath.Join(datedir, filepath.Base(file))
|
|
filelog.Info("dest: %s", dest)
|
|
err = os.MkdirAll(datedir, 0755)
|
|
if err != nil {
|
|
filelog.Error("error creating directory: %s", err)
|
|
return
|
|
}
|
|
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
|
|
}
|
|
|
|
filelog.Debug("opening input file")
|
|
in, err := os.Open(file)
|
|
if err != nil {
|
|
filelog.Error("error opening file: %s", err)
|
|
return
|
|
}
|
|
filelog.Debug("opening output file %s", dest)
|
|
out, err := os.Create(dest)
|
|
if err != nil {
|
|
filelog.Error("error creating dest file: %s", err)
|
|
in.Close()
|
|
return
|
|
}
|
|
filelog.Info("copying file")
|
|
_, err = io.Copy(out, in)
|
|
in.Close()
|
|
out.Close()
|
|
if err != nil {
|
|
filelog.Error("error copying file: %s", err)
|
|
return
|
|
}
|
|
|
|
filelog.Info("removing original file")
|
|
err = os.Remove(file)
|
|
if err != nil {
|
|
filelog.Error("error removing original 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")
|
|
}
|