feat: add desktop notifications
This commit is contained in:
parent
f58fb5133e
commit
4240d6f017
5 changed files with 71 additions and 18 deletions
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -1,3 +1,13 @@
|
|||
# 1.4.0
|
||||
|
||||
**New features**
|
||||
|
||||
- optional desktop notifications on errors
|
||||
|
||||
**Notable bug fixes**
|
||||
|
||||
- the toolArgs option now understands complex patterns (spaces, quotes)
|
||||
|
||||
# 1.3.0
|
||||
|
||||
**Breaking changes**
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
- upgrade version number
|
||||
- in main
|
||||
- in man page
|
||||
- update changelog
|
|
@ -1,4 +1,4 @@
|
|||
.TH clipman 1 1.3.0 ""
|
||||
.TH clipman 1 1.4.0 ""
|
||||
.SH "NAME"
|
||||
clipman
|
||||
.SH "SYNOPSIS"
|
||||
|
@ -15,6 +15,9 @@ Show context-sensitive help (also try --help-long and --help-man).
|
|||
\fB--histpath="~/.local/share/clipman.json"\fR
|
||||
Path of history file
|
||||
.TP
|
||||
\fB--notify\fR
|
||||
Send desktop notifications on errors
|
||||
.TP
|
||||
\fB-v, --version\fR
|
||||
Show application version.
|
||||
.SH "COMMANDS"
|
||||
|
|
26
main.go
26
main.go
|
@ -7,7 +7,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
@ -15,11 +14,12 @@ import (
|
|||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
const version = "1.3.0"
|
||||
const version = "1.4.0"
|
||||
|
||||
var (
|
||||
app = kingpin.New("clipman", "A clipboard manager for Wayland")
|
||||
histpath = app.Flag("histpath", "Path of history file").Default("~/.local/share/clipman.json").String()
|
||||
alert = app.Flag("notify", "Send desktop notifications on errors").Bool()
|
||||
|
||||
storer = app.Command("store", "Record clipboard events (run as argument to `wl-paste --watch`)")
|
||||
maxDemon = storer.Flag("max-items", "history size").Default("15").Int()
|
||||
|
@ -47,7 +47,7 @@ func main() {
|
|||
|
||||
histfile, history, err := getHistory(*histpath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
smartLog(err.Error(), "critical", *alert)
|
||||
}
|
||||
|
||||
switch action {
|
||||
|
@ -59,18 +59,18 @@ func main() {
|
|||
stdin = append(stdin, scanner.Text())
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
log.Fatal("Error getting input from stdin.")
|
||||
smartLog("Couldn't get input from stdin.", "critical", *alert)
|
||||
}
|
||||
text := strings.Join(stdin, "\n")
|
||||
|
||||
persist := !*noPersist
|
||||
if err := store(text, history, histfile, *maxDemon, persist); err != nil {
|
||||
log.Fatal(err)
|
||||
smartLog(err.Error(), "critical", *alert)
|
||||
}
|
||||
case "pick":
|
||||
selection, err := selector(history, *maxPicker, *pickTool, "pick", *pickToolArgs)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
smartLog(err.Error(), "normal", *alert)
|
||||
}
|
||||
|
||||
if selection != "" {
|
||||
|
@ -79,7 +79,7 @@ func main() {
|
|||
}
|
||||
case "restore":
|
||||
if len(history) == 0 {
|
||||
log.Println("Nothing to restore")
|
||||
fmt.Println("Nothing to restore")
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ func main() {
|
|||
// remove all history
|
||||
if *clearAll {
|
||||
if err := wipeAll(histfile); err != nil {
|
||||
log.Fatal(err)
|
||||
smartLog(err.Error(), "normal", *alert)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ func main() {
|
|||
|
||||
selection, err := selector(history, *maxClearer, *clearTool, "clear", *clearToolArgs)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
smartLog(err.Error(), "normal", *alert)
|
||||
}
|
||||
|
||||
if selection == "" {
|
||||
|
@ -111,7 +111,7 @@ func main() {
|
|||
// there was only one possible item we could select, and we selected it,
|
||||
// so wipe everything
|
||||
if err := wipeAll(histfile); err != nil {
|
||||
log.Fatal(err)
|
||||
smartLog(err.Error(), "normal", *alert)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ func main() {
|
|||
}
|
||||
|
||||
if err := write(filter(history, selection), histfile); err != nil {
|
||||
log.Fatal(err)
|
||||
smartLog(err.Error(), "critical", *alert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,12 +171,12 @@ func getHistory(rawPath string) (string, []string, error) {
|
|||
func serveTxt(s string) {
|
||||
bin, err := exec.LookPath("wl-copy")
|
||||
if err != nil {
|
||||
log.Printf("couldn't find wl-copy: %v\n", err)
|
||||
smartLog(fmt.Sprintf("couldn't find wl-copy: %v\n", err), "low", *alert)
|
||||
}
|
||||
|
||||
// we mandate the mime type because we know we can only serve text; not doing this leads to weird bugs like #35
|
||||
cmd := exec.Cmd{Path: bin, Args: []string{bin, "-t", "TEXT"}, Stdin: strings.NewReader(s)}
|
||||
if err := cmd.Run(); err != nil {
|
||||
log.Printf("error running wl-copy: %s\n", err)
|
||||
smartLog(fmt.Sprintf("error running wl-copy: %s\n", err), "low", *alert)
|
||||
}
|
||||
}
|
||||
|
|
44
notify.go
Normal file
44
notify.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os/exec"
|
||||
"time"
|
||||
)
|
||||
|
||||
func smartLog(message, urgency string, alert bool) {
|
||||
if alert {
|
||||
if err := notify(message, urgency); err != nil {
|
||||
log.Printf("failure sending notification: %s\n", err)
|
||||
}
|
||||
}
|
||||
|
||||
switch urgency {
|
||||
case "critical", "normal":
|
||||
log.Fatal(message)
|
||||
default:
|
||||
log.Println(message)
|
||||
}
|
||||
}
|
||||
|
||||
func notify(message string, urgency string) error {
|
||||
var timeout time.Duration
|
||||
switch urgency {
|
||||
// cases accepted by notify-send: low, normal, critical
|
||||
case "critical":
|
||||
timeout = 5 * time.Second
|
||||
case "low":
|
||||
timeout = 2 * time.Second
|
||||
default:
|
||||
timeout = 3 * time.Second
|
||||
}
|
||||
|
||||
// notify-send only accepts milliseconds
|
||||
millisec := fmt.Sprintf("%v", timeout.Seconds()*1000)
|
||||
|
||||
args := []string{"-a", "Clipman", "-u", urgency, "-t", millisec, message}
|
||||
|
||||
return exec.Command("notify-send", args...).Run()
|
||||
|
||||
}
|
Loading…
Reference in a new issue