goveal/fs/watching_fs.go
Peter Kurfer 82a651cd5d
First draft of new fiber based server
- replaced previous net/http based muxer and all other components with fiber
- replaced polling with SSE to handle file changes
- auto-update custom stylesheets
- natively support mermaid diagrams
- handle custom element attributes for lists properly
- reload on config changes
- replace JS templating with actual JS code and an API
2021-12-22 11:52:02 +01:00

66 lines
1.2 KiB
Go

package fs
import (
"io/fs"
"path/filepath"
"time"
"github.com/fsnotify/fsnotify"
log "github.com/sirupsen/logrus"
)
type Event struct {
File string
Timestamp time.Time
}
func NewWatching(backing FS) (*Watching, error) {
watcher, err := fsnotify.NewWatcher()
if err != nil {
return nil, err
}
return &Watching{
watcher: watcher,
backing: backing,
}, nil
}
type Watching struct {
events chan Event
watcher *fsnotify.Watcher
backing FS
}
func (w *Watching) Open(name string) (file fs.File, err error) {
file, err = w.backing.Open(name)
if err == nil {
dir := filepath.Dir(name)
if watchErr := w.watcher.Add(dir); watchErr != nil {
log.Errorf("Failed to watch %s: %v", dir, watchErr)
}
return file, nil
}
return nil, err
}
func (w *Watching) Events() chan Event {
if w.events == nil {
w.events = make(chan Event)
go transportEvents(w.watcher.Events, w.events)
}
return w.events
}
func (w *Watching) Close() error {
return w.watcher.Close()
}
func transportEvents(in <-chan fsnotify.Event, out chan<- Event) {
for ev := range in {
ev.Name = filepath.Base(ev.Name)
out <- Event{
File: ev.Name,
Timestamp: time.Now(),
}
}
}