package main import ( "errors" "flag" "fmt" "log" "os" "os/signal" "path/filepath" "time" "git.trj.tw/golang/go-watch-webp/module/config" "git.trj.tw/golang/go-watch-webp/module/image" "git.trj.tw/golang/go-watch-webp/module/option" "git.trj.tw/golang/utils" "gopkg.in/fsnotify.v1" ) func init() { option.RegOptions() } func main() { fmt.Println("watch dir webp image") var err error lock := make(chan os.Signal, 1) signal.Notify(lock, os.Interrupt) opts := option.GetOptions() if opts.Help { flag.Usage() return } err = config.LoadConfig(opts.Config) if err != nil { log.Fatal(err) } conf := config.GetConfig() if exists := checkDirectory(conf.Src); !exists { log.Fatal(errors.New("source folder not exists")) } if exists := checkDirectory(conf.Dist); !exists { log.Fatal(errors.New("target folder not exists")) } watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) } // watch fs notify go func() { for { select { case event, ok := <-watcher.Events: if !ok { return } log.Println("fs event :: ", event) if event.Op&fsnotify.Create == fsnotify.Create { log.Println("create file :: ", event.Name) go procFile(event.Name) } case err, ok := <-watcher.Errors: if !ok { return } log.Println("error: ", err) } } }() err = watcher.Add(conf.Src) if err != nil { log.Fatal(err) } <-lock } func procFile(loc string) { // only proc webp file if ext := filepath.Ext(loc); ext != ".webp" { return } go func(loc string) { defer func() { os.Remove(loc) }() fin := waitFile(loc) if fin { log.Println("file write ok") file, err := os.Open(loc) if err != nil { log.Println("err :: ", err) } defer file.Close() err = image.ConvertToPng(file) if err != nil { log.Println("err :: ", err) } } }(loc) } func waitFile(loc string) bool { if len(loc) == 0 { return false } for { // check file modify time t1, err := getFileModTime(loc) if err != nil { return false } time.Sleep(100 * time.Millisecond) t2, err := getFileModTime(loc) if err != nil { return false } if t1 == t2 { break } } return true } func getFileModTime(loc string) (int64, error) { file, err := os.Open(loc) if err != nil { return -1, err } defer file.Close() info, err := file.Stat() if err != nil { return -1, err } return info.ModTime().UnixNano(), nil } func checkDirectory(dir string) bool { if len(dir) == 0 { return false } dir = utils.ParsePath(dir) if exists := utils.CheckExists(dir, true); !exists { return false } if isDir := utils.IsDir(dir); !isDir { return false } return true }