init commit
This commit is contained in:
113
internal/service/monitor.go
Normal file
113
internal/service/monitor.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/yeho/klp/internal/clipboard"
|
||||
"github.com/yeho/klp/internal/config"
|
||||
"github.com/yeho/klp/internal/database"
|
||||
)
|
||||
|
||||
type Monitor struct {
|
||||
cfg *config.Config
|
||||
db *database.Database
|
||||
clipboard clipboard.Clipboard
|
||||
}
|
||||
|
||||
func NewMonitor(cfg *config.Config, db *database.Database) (*Monitor, error) {
|
||||
clip, err := clipboard.New()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize clipboard: %w", err)
|
||||
}
|
||||
|
||||
return &Monitor{
|
||||
cfg: cfg,
|
||||
db: db,
|
||||
clipboard: clip,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (m *Monitor) Run() error {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
// Handle shutdown signals
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
|
||||
|
||||
go func() {
|
||||
<-sigChan
|
||||
fmt.Println("\nShutting down...")
|
||||
cancel()
|
||||
}()
|
||||
|
||||
fmt.Println("Clipboard monitor started. Press Ctrl+C to stop.")
|
||||
|
||||
changes := m.clipboard.Watch(ctx)
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil
|
||||
case content, ok := <-changes:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if err := m.handleChange(content); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error handling clipboard change: %v\n", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Monitor) handleChange(content string) error {
|
||||
// Skip empty content
|
||||
if content == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check max entry size if configured
|
||||
if m.cfg.MaxEntrySize > 0 && len(content) > m.cfg.MaxEntrySize {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Skip if duplicate of most recent entry
|
||||
recent := m.db.MostRecent()
|
||||
if recent != nil && recent.Value == content {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Add to database
|
||||
entry, err := m.db.Add(content)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Log the addition (truncate for display)
|
||||
preview := content
|
||||
if len(preview) > 50 {
|
||||
preview = preview[:50] + "..."
|
||||
}
|
||||
// Replace newlines for cleaner display
|
||||
preview = replaceNewlines(preview)
|
||||
fmt.Printf("Added [%s]: %s\n", entry.ID, preview)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func replaceNewlines(s string) string {
|
||||
result := make([]byte, 0, len(s))
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] == '\n' {
|
||||
result = append(result, ' ')
|
||||
} else if s[i] == '\r' {
|
||||
// skip
|
||||
} else {
|
||||
result = append(result, s[i])
|
||||
}
|
||||
}
|
||||
return string(result)
|
||||
}
|
||||
Reference in New Issue
Block a user