104 lines
1.8 KiB
Go
104 lines
1.8 KiB
Go
package watcher
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
|
|
"docproc/processor"
|
|
|
|
"github.com/fsnotify/fsnotify"
|
|
)
|
|
|
|
type Watcher struct {
|
|
proc *processor.Processor
|
|
watcher *fsnotify.Watcher
|
|
inbox string
|
|
stop chan struct{}
|
|
}
|
|
|
|
func New(proc *processor.Processor) (*Watcher, error) {
|
|
homeDir, _ := os.UserHomeDir()
|
|
inbox := filepath.Join(homeDir, "documents", "inbox")
|
|
|
|
// Ensure inbox exists
|
|
os.MkdirAll(inbox, 0755)
|
|
|
|
fsWatcher, err := fsnotify.NewWatcher()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := fsWatcher.Add(inbox); err != nil {
|
|
fsWatcher.Close()
|
|
return nil, err
|
|
}
|
|
|
|
return &Watcher{
|
|
proc: proc,
|
|
watcher: fsWatcher,
|
|
inbox: inbox,
|
|
stop: make(chan struct{}),
|
|
}, nil
|
|
}
|
|
|
|
func (w *Watcher) Watch() {
|
|
// Process any existing files first
|
|
w.processExisting()
|
|
|
|
for {
|
|
select {
|
|
case event, ok := <-w.watcher.Events:
|
|
if !ok {
|
|
return
|
|
}
|
|
if event.Op&fsnotify.Create == fsnotify.Create {
|
|
// Small delay to ensure file is fully written
|
|
time.Sleep(500 * time.Millisecond)
|
|
w.processFile(event.Name)
|
|
}
|
|
case err, ok := <-w.watcher.Errors:
|
|
if !ok {
|
|
return
|
|
}
|
|
log.Printf("Watcher error: %v", err)
|
|
case <-w.stop:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func (w *Watcher) processExisting() {
|
|
entries, err := os.ReadDir(w.inbox)
|
|
if err != nil {
|
|
log.Printf("Failed to read inbox: %v", err)
|
|
return
|
|
}
|
|
|
|
for _, entry := range entries {
|
|
if entry.IsDir() {
|
|
continue
|
|
}
|
|
path := filepath.Join(w.inbox, entry.Name())
|
|
w.processFile(path)
|
|
}
|
|
}
|
|
|
|
func (w *Watcher) processFile(path string) {
|
|
ext := strings.ToLower(filepath.Ext(path))
|
|
if ext != ".pdf" && ext != ".png" && ext != ".jpg" && ext != ".jpeg" {
|
|
return
|
|
}
|
|
|
|
if err := w.proc.ProcessFile(path); err != nil {
|
|
log.Printf("Failed to process %s: %v", path, err)
|
|
}
|
|
}
|
|
|
|
func (w *Watcher) Stop() {
|
|
close(w.stop)
|
|
w.watcher.Close()
|
|
}
|