organizer/watch_directory.go

96 lines
1.9 KiB
Go
Raw Permalink Normal View History

2023-01-13 19:23:36 +01:00
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/fsnotify/fsnotify"
)
func WatchDirectory(op fsnotify.Op, path string) (<-chan string, error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
panic(err) // TODO error handling
}
err = watcher.Add(path)
if err != nil {
return nil, err
}
files, err := os.ReadDir(path)
if err != nil {
return nil, err
}
ch := make(chan string, 10)
2023-01-19 12:05:46 +01:00
// close channel on app shutdown
go func() {
<-AppCtx.Done()
watcher.Close()
}()
AppExitWg.Add(1)
2023-01-13 19:23:36 +01:00
go func(watcher *fsnotify.Watcher, ch chan<- string) {
2023-01-19 12:05:46 +01:00
defer AppExitWg.Done()
2023-01-13 19:23:36 +01:00
defer watcher.Close()
for _, file := range files {
path := filepath.Join(path, file.Name())
if file.IsDir() {
//fmt.Println("watching directory", path)
watcher.Add(path)
if dirFiles, err := os.ReadDir(path); err == nil {
for _, dirFile := range dirFiles {
ch <- filepath.Join(path, dirFile.Name())
}
}
} else {
ch <- path
}
}
for {
select {
case event, ok := <-watcher.Events:
if !ok {
close(ch)
return
}
if fi, err := os.Stat(event.Name); err == nil && fi.IsDir() {
if event.Op&fsnotify.Create == fsnotify.Create {
//fmt.Println("watching directory", event.Name)
watcher.Add(event.Name)
}
// read dir immediately because directory files could simultanously with its parent directory
if dirFiles, err := os.ReadDir(event.Name); err == nil {
for _, dirFile := range dirFiles {
ch <- filepath.Join(event.Name, dirFile.Name())
}
}
} else if err != nil && event.Op&fsnotify.Remove == fsnotify.Remove {
//fmt.Println("stopped watching directory", event.Name)
watcher.Remove(event.Name)
}
if event.Op&op == op {
ch <- event.Name
}
case err, ok := <-watcher.Errors:
2023-01-19 12:05:46 +01:00
if ok {
fmt.Println(err, ok)
}
2023-01-13 19:23:36 +01:00
close(ch)
return
}
}
}(watcher, ch)
return ch, nil
}