Skip to content

Commit

Permalink
Apply suggestions
Browse files Browse the repository at this point in the history
Signed-off-by: eternal-flame-AD <[email protected]>
  • Loading branch information
eternal-flame-AD committed Aug 5, 2024
1 parent a0550b1 commit fca4b2c
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 71 deletions.
44 changes: 20 additions & 24 deletions command/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,8 @@ func Push() cli.Command {
func doPush(ctx *cli.Context) {
conf, confErr := config.ReadConfig(config.GetLocations())

msgText := make(chan string)
null := '\x00'
if ctx.Bool("no-split") {
go readMessage(ctx.Args(), os.Stdin, msgText, nil)
} else {
go readMessage(ctx.Args(), os.Stdin, msgText, &null)
}
msgTextChan := make(chan string)
go readMessage(ctx.Args(), os.Stdin, msgTextChan, !ctx.Bool("no-split"))

priority := ctx.Int("priority")
title := ctx.String("title")
Expand Down Expand Up @@ -81,8 +76,24 @@ func doPush(ctx *cli.Context) {
return
}

parsedExtras := make(map[string]interface{})

if contentType != "" {
parsedExtras["client::display"] = map[string]interface{}{
"contentType": contentType,
}
}

if clickUrl != "" {
parsedExtras["client::notification"] = map[string]interface{}{
"click": map[string]string{
"url": clickUrl,
},
}
}

var sent bool
for msgText := range msgText {
for msgText := range msgTextChan {
if !ctx.Bool("disable-unescape-backslash") {
msgText = utils.Evaluate(msgText)
}
Expand All @@ -91,22 +102,7 @@ func doPush(ctx *cli.Context) {
Message: msgText,
Title: title,
Priority: priority,
}

msg.Extras = map[string]interface{}{}

if contentType != "" {
msg.Extras["client::display"] = map[string]interface{}{
"contentType": contentType,
}
}

if clickUrl != "" {
msg.Extras["client::notification"] = map[string]interface{}{
"click": map[string]string{
"url": clickUrl,
},
}
Extras: parsedExtras,
}

pushMessage(parsedURL, token, msg, quiet)
Expand Down
70 changes: 29 additions & 41 deletions command/read.go
Original file line number Diff line number Diff line change
@@ -1,61 +1,49 @@
package command

import (
"bufio"
"errors"
"io"
"strings"

"github.com/gotify/cli/v2/utils"
)

func readMessage(args []string, r io.Reader, output chan<- string, split *rune) {
msgArgs := strings.Join(args, " ")
func readMessage(args []string, r io.Reader, output chan<- string, splitOnNull bool) {
defer close(output)

if msgArgs != "" {
switch {
case len(args) > 0:
if utils.ProbeStdin(r) {
utils.Exit1With("message is set via arguments and stdin, use only one of them")
}

output <- msgArgs
close(output)
return
}

var buf strings.Builder
for {
var tmp [256]byte
n, err := r.Read(tmp[:])
if err != nil {
if err.Error() == "EOF" {
break
output <- strings.Join(args, " ")
case splitOnNull:
read := bufio.NewReader(r)
for {
s, err := read.ReadString('\x00')
if err != nil {
if !errors.Is(err, io.EOF) {
utils.Exit1With("read error", err)
}
if len(s) > 0 {
output <- s
}
return
} else {
if len(s) > 1 {
output <- strings.TrimSuffix(s, "\x00")
}
}
utils.Exit1With(err)
}
tmpStr := string(tmp[:n])
if split != nil {
// split the message on the null character
parts := strings.Split(tmpStr, string(*split))
if len(parts) == 1 {
buf.WriteString(parts[0])
continue
}

previous := buf.String()
// fuse previous with parts[0], send parts[1] .. parts[n-2] and set parts[n-1] as new previous
firstMsg := previous + parts[0]
output <- firstMsg
for _, part := range parts[1 : len(parts)-1] {
output <- part
}
buf.Reset()
buf.WriteString(parts[len(parts)-1])
} else {
buf.WriteString(tmpStr)
default:
bytes, err := io.ReadAll(r)
if err != nil {
utils.Exit1With("cannot read", err)
}
output <- string(bytes)
return
}

if buf.Len() > 0 {
output <- buf.String()
}

close(output)
}
42 changes: 37 additions & 5 deletions command/read_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package command

import (
"bufio"
"bytes"
"strings"
"testing"
)
Expand All @@ -27,29 +29,59 @@ func readChanAll[T any](c chan T) []T {
}

func TestReadMessage(t *testing.T) {
var split rune = '\x00'

if bytes.IndexByte([]byte("Hello\x00World"), '\x00') != len("Hello") {
t.Errorf("Expected %v, but got %v", len("Hello"), bytes.IndexByte([]byte("Hello\x00World"), '\x00'))
}
rdr := bufio.NewReader(strings.NewReader("Hello\x00World"))
if s, _ := rdr.ReadString('\x00'); s != "Hello\x00" {
t.Errorf("Expected %x, but got %x", "Hello\x00", s)
}
// Test case 1: message set via arguments
output := make(chan string)
go readMessage([]string{"Hello", "World"}, nil, output, nil)
go readMessage([]string{"Hello", "World"}, nil, output, false)

if res := readChanAll(output); !(slicesEqual(res, []string{"Hello World"})) {
t.Errorf("Expected %v, but got %v", []string{"Hello World"}, res)
}

// Test case 2: message set via arguments should not split on 'split' character
output = make(chan string)
go readMessage([]string{"Hello\x00World"}, nil, output, &split)
go readMessage([]string{"Hello\x00World"}, nil, output, true)

if res := readChanAll(output); !(slicesEqual(res, []string{"Hello\x00World"})) {
t.Errorf("Expected %v, but got %v", []string{"Hello\x00World"}, res)
}

// Test case 3: message set via stdin
output = make(chan string)
go readMessage([]string{}, strings.NewReader("Hello\x00World"), output, &split)
go readMessage([]string{}, strings.NewReader("Hello\x00World"), output, true)

if res := readChanAll(output); !(slicesEqual(res, []string{"Hello", "World"})) {
t.Errorf("Expected %v, but got %v", []string{"Hello", "World"}, res)
}

// Test case 4: multiple null bytes should be split as one
output = make(chan string)
go readMessage([]string{}, strings.NewReader("Hello\x00\x00World"), output, true)

if res := readChanAll(output); !(slicesEqual(res, []string{"Hello", "World"})) {
t.Errorf("Expected %v, but got %v", []string{"Hello", "World"}, res)
}

// Test case 5: multiple null bytes at the end should be split as one
output = make(chan string)
go readMessage([]string{}, strings.NewReader("Hello\x00\x00"), output, true)

if res := readChanAll(output); !(slicesEqual(res, []string{"Hello"})) {
t.Errorf("Expected %v, but got %v", []string{"Hello"}, res)
}

// Test case 6: multiple null bytes at the start should be split as one
output = make(chan string)
go readMessage([]string{}, strings.NewReader("\x00\x00World"), output, true)

if res := readChanAll(output); !(slicesEqual(res, []string{"World"})) {
t.Errorf("Expected %v, but got %v", []string{"World"}, res)
}

}
2 changes: 1 addition & 1 deletion command/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ func doWatch(ctx *cli.Context) {
fmt.Fprintln(msgData, output)
fmt.Fprintln(msgData, "== END NEW OUTPUT ==")
case "short":
fmt.Fprintln(msgData, output)
fmt.Fprint(msgData, output)
}

msgString := msgData.String()
Expand Down

0 comments on commit fca4b2c

Please sign in to comment.