Skip to content

Commit

Permalink
Merge pull request #16 from altid/altid-cli
Browse files Browse the repository at this point in the history
Altid cli
  • Loading branch information
halfwit committed Mar 15, 2020
2 parents 29c64f1 + 88e4711 commit 17aea60
Show file tree
Hide file tree
Showing 19 changed files with 297 additions and 245 deletions.
9 changes: 8 additions & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"

"github.com/altid/libs/fs"
"github.com/lionkov/go9p/p"
)

Expand Down Expand Up @@ -44,7 +45,7 @@ type runner interface {
connect(int) error
attach() error
auth() error
ctl(int, ...string) (int, error) // Just call write at the end in nested types
ctl(int, ...string) (int, error)
tabs() ([]byte, error)
title() ([]byte, error)
status() ([]byte, error)
Expand All @@ -53,6 +54,7 @@ type runner interface {
notifications() ([]byte, error)
feed() (io.ReadCloser, error)
document() ([]byte, error)
getCommands() ([]*fs.Command, error)
}

// NewClient returns a client ready to connect to addr
Expand All @@ -79,6 +81,11 @@ func NewMockClient(addr string) *Client {
}
}

// GetCommands returns a list of available commands for the connected service
func (c Client) GetCommands() ([]*fs.Command, error) {
return c.run.getCommands()
}

// Document returns the contents of a document file on the host
// if it exists, or an error
func (c *Client) Document() ([]byte, error) {
Expand Down
11 changes: 11 additions & 0 deletions client/client_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net"

"github.com/altid/libs/fs"
"github.com/knieriem/g/go9p/user"
"github.com/lionkov/go9p/p"
"github.com/lionkov/go9p/p/clnt"
Expand Down Expand Up @@ -125,6 +126,16 @@ func (c *client) notifications() ([]byte, error) {
return c.clnt.Read(nfid, 0, p.MSIZE)
}

func (c *client) getCommands() ([]*fs.Command, error) {
_, err := getNamedFile(c, "ctl")
if err != nil {
return nil, err
}
// Parse into Command struct

return nil, nil
}

func (c *client) feed() (io.ReadCloser, error) {
nfid := c.clnt.FidAlloc()

Expand Down
6 changes: 6 additions & 0 deletions client/client_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"
"time"

"github.com/altid/libs/fs"
fuzz "github.com/google/gofuzz"
)

Expand Down Expand Up @@ -39,6 +40,11 @@ func (c *mock) auth() error {
return nil
}

func (c *mock) getCommands() ([]*fs.Command, error) {
// TODO(halfwit): Mock up a general: list
return nil, nil
}

// We want to eventually create and track tabs internally to the library
func (c *mock) ctl(cmd int, args ...string) (int, error) {
data, err := runClientCtl(cmd, args...)
Expand Down
2 changes: 1 addition & 1 deletion client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func TestCommands(t *testing.T) {
if _, e := mc.Input([]byte("Some text")); e != nil {
t.Error(e)
}

if _, e := mc.Open("chicken"); e != nil {
t.Error(e)
}
Expand Down
160 changes: 160 additions & 0 deletions client/cmd/altid-cli/listen.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
package main

import (
"bufio"
"errors"
"io"
"os"
"strings"
"time"

"github.com/altid/libs/client"
)

type listener struct {
err chan error
data chan []byte
done chan struct{}
rd *bufio.Reader
c *client.Client
}

func newListener(c *client.Client) *listener {
return &listener{
rd: bufio.NewReader(os.Stdin),
err: make(chan error),
data: make(chan []byte),
done: make(chan struct{}),
c: c,
}
}

func (l *listener) listen() {
if emitFeedData(l) != nil && emitDocumentData(l) != nil {
l.err <- errors.New("Unable to find feed or document for given buffer")
return
}

for {
line, err := l.rd.ReadString('\n')
if err != nil && err != io.EOF {
l.err <- err
return
}

if line == "/quit" {
l.done <- struct{}{}
return
}

handle(l, strings.Fields(line))
}
}

func handle(l *listener, args []string) {
switch args[0] {
case "/help":
l.data <- []byte(usage)
case "/buffer":
sendCmd(l, l.c.Buffer, args[1])
case "/open":
sendCmd(l, l.c.Open, args[1])
case "/close":
sendCmd(l, l.c.Close, args[1])
// TODO(halfwit): We want to track the current buffer
// and only send the `from` field internally
case "/link":
//sendCmd(l, l.c.Link, 2, args)
case "/tabs":
getData(l, l.c.Tabs)
case "/title":
getData(l, l.c.Title)
case "/status":
getData(l, l.c.Status)
case "/aside":
getData(l, l.c.Aside)
case "/notify":
getData(l, l.c.Notifications)
default:
otherMsg(l, args)
}
}

func otherMsg(l *listener, args []string) {
if args[0][0] == '/' {
//cl.Ctl([]byte(line[1:]))
return
}

line := strings.Join(args, " ")
l.c.Input([]byte(line))
}

func emitDocumentData(l *listener) error {
f, err := l.c.Document()
if err != nil {
return err
}

if len(f) > 0 {
l.data <- f
}

return nil
}

func emitFeedData(l *listener) error {
f, err := l.c.Feed()
if err != nil {
return err
}

go func() {
defer f.Close()

for {
// Ensure your buffer is MSIZE
b := make([]byte, client.MSIZE)

_, err := f.Read(b)
if err != nil {
l.err <- err
return
}

if len(b) > 0 {
l.data <- b
}
}
}()

return nil
}

func sendCmd(l *listener, fn func(string) (int, error), args ...string) {
if len(args) != 1 {
l.err <- errBadArgs
return
}

if _, err := fn(args[0]); err != nil {
l.err <- err
return
}

time.Sleep(time.Millisecond * 200)
if emitFeedData(l) != nil && emitDocumentData(l) != nil {
l.err <- errors.New("Unable to find feed or document for given buffer")
}
}

func getData(l *listener, fn func() ([]byte, error)) {
t, err := fn()
if err != nil {
l.err <- err
return
}

l.data <- t
return
}
Loading

0 comments on commit 17aea60

Please sign in to comment.