mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-04-12 07:10:05 +03:00
ssh-chat/chat/{message,user,theme,history} -> ssh-chat/chat/message
This commit is contained in:
parent
2ebd77af6a
commit
c2adb4d632
@ -6,6 +6,8 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
)
|
||||
|
||||
// The error returned when an invalid command is issued.
|
||||
@ -29,7 +31,7 @@ type Command struct {
|
||||
PrefixHelp string
|
||||
// If omitted, command is hidden from /help
|
||||
Help string
|
||||
Handler func(*Room, CommandMsg) error
|
||||
Handler func(*Room, message.CommandMsg) error
|
||||
// Command requires Op permissions
|
||||
Op bool
|
||||
}
|
||||
@ -59,7 +61,7 @@ func (c Commands) Alias(command string, alias string) error {
|
||||
}
|
||||
|
||||
// Run executes a command message.
|
||||
func (c Commands) Run(room *Room, msg CommandMsg) error {
|
||||
func (c Commands) Run(room *Room, msg message.CommandMsg) error {
|
||||
if msg.From == nil {
|
||||
return ErrNoOwner
|
||||
}
|
||||
@ -84,9 +86,9 @@ func (c Commands) Help(showOp bool) string {
|
||||
normal = append(normal, cmd)
|
||||
}
|
||||
}
|
||||
help := "Available commands:" + Newline + NewCommandsHelp(normal).String()
|
||||
help := "Available commands:" + message.Newline + NewCommandsHelp(normal).String()
|
||||
if showOp {
|
||||
help += Newline + "-> Operator commands:" + Newline + NewCommandsHelp(op).String()
|
||||
help += message.Newline + "-> Operator commands:" + message.Newline + NewCommandsHelp(op).String()
|
||||
}
|
||||
return help
|
||||
}
|
||||
@ -102,24 +104,24 @@ func init() {
|
||||
func InitCommands(c *Commands) {
|
||||
c.Add(Command{
|
||||
Prefix: "/help",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
op := room.IsOp(msg.From())
|
||||
room.Send(NewSystemMsg(room.commands.Help(op), msg.From()))
|
||||
room.Send(message.NewSystemMsg(room.commands.Help(op), msg.From()))
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
||||
c.Add(Command{
|
||||
Prefix: "/me",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
me := strings.TrimLeft(msg.body, "/me")
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
me := strings.TrimLeft(msg.Body(), "/me")
|
||||
if me == "" {
|
||||
me = "is at a loss for words."
|
||||
} else {
|
||||
me = me[1:]
|
||||
}
|
||||
|
||||
room.Send(NewEmoteMsg(me, msg.From()))
|
||||
room.Send(message.NewEmoteMsg(me, msg.From()))
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@ -127,7 +129,7 @@ func InitCommands(c *Commands) {
|
||||
c.Add(Command{
|
||||
Prefix: "/exit",
|
||||
Help: "Exit the chat.",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
msg.From().Close()
|
||||
return nil
|
||||
},
|
||||
@ -138,7 +140,7 @@ func InitCommands(c *Commands) {
|
||||
Prefix: "/nick",
|
||||
PrefixHelp: "NAME",
|
||||
Help: "Rename yourself.",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
args := msg.Args()
|
||||
if len(args) != 1 {
|
||||
return ErrMissingArg
|
||||
@ -164,11 +166,11 @@ func InitCommands(c *Commands) {
|
||||
c.Add(Command{
|
||||
Prefix: "/names",
|
||||
Help: "List users who are connected.",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
// TODO: colorize
|
||||
names := room.NamesPrefix("")
|
||||
body := fmt.Sprintf("%d connected: %s", len(names), strings.Join(names, ", "))
|
||||
room.Send(NewSystemMsg(body, msg.From()))
|
||||
room.Send(message.NewSystemMsg(body, msg.From()))
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@ -178,7 +180,7 @@ func InitCommands(c *Commands) {
|
||||
Prefix: "/theme",
|
||||
PrefixHelp: "[mono|colors]",
|
||||
Help: "Set your color theme.",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
user := msg.From()
|
||||
args := msg.Args()
|
||||
if len(args) == 0 {
|
||||
@ -187,16 +189,16 @@ func InitCommands(c *Commands) {
|
||||
theme = user.Config.Theme.Id()
|
||||
}
|
||||
body := fmt.Sprintf("Current theme: %s", theme)
|
||||
room.Send(NewSystemMsg(body, user))
|
||||
room.Send(message.NewSystemMsg(body, user))
|
||||
return nil
|
||||
}
|
||||
|
||||
id := args[0]
|
||||
for _, t := range Themes {
|
||||
for _, t := range message.Themes {
|
||||
if t.Id() == id {
|
||||
user.Config.Theme = &t
|
||||
body := fmt.Sprintf("Set theme: %s", id)
|
||||
room.Send(NewSystemMsg(body, user))
|
||||
room.Send(message.NewSystemMsg(body, user))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -207,7 +209,7 @@ func InitCommands(c *Commands) {
|
||||
c.Add(Command{
|
||||
Prefix: "/quiet",
|
||||
Help: "Silence room announcements.",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
u := msg.From()
|
||||
u.ToggleQuietMode()
|
||||
|
||||
@ -217,7 +219,7 @@ func InitCommands(c *Commands) {
|
||||
} else {
|
||||
body = "Quiet mode is toggled OFF"
|
||||
}
|
||||
room.Send(NewSystemMsg(body, u))
|
||||
room.Send(message.NewSystemMsg(body, u))
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@ -225,7 +227,7 @@ func InitCommands(c *Commands) {
|
||||
c.Add(Command{
|
||||
Prefix: "/slap",
|
||||
PrefixHelp: "NAME",
|
||||
Handler: func(room *Room, msg CommandMsg) error {
|
||||
Handler: func(room *Room, msg message.CommandMsg) error {
|
||||
var me string
|
||||
args := msg.Args()
|
||||
if len(args) == 0 {
|
||||
@ -234,7 +236,7 @@ func InitCommands(c *Commands) {
|
||||
me = fmt.Sprintf("slaps %s around a bit with a large trout.", strings.Join(args, " "))
|
||||
}
|
||||
|
||||
room.Send(NewEmoteMsg(me, msg.From()))
|
||||
room.Send(message.NewEmoteMsg(me, msg.From()))
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
)
|
||||
|
||||
type helpItem struct {
|
||||
@ -54,5 +56,5 @@ func (h help) String() string {
|
||||
}
|
||||
|
||||
sort.Strings(r)
|
||||
return strings.Join(r, Newline)
|
||||
return strings.Join(r, message.Newline)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import "testing"
|
||||
|
26
chat/message/identity.go
Normal file
26
chat/message/identity.go
Normal file
@ -0,0 +1,26 @@
|
||||
package message
|
||||
|
||||
// Identifier is an interface that can uniquely identify itself.
|
||||
type Identifier interface {
|
||||
Id() string
|
||||
SetId(string)
|
||||
Name() string
|
||||
}
|
||||
|
||||
// SimpleId is a simple Identifier implementation used for testing.
|
||||
type SimpleId string
|
||||
|
||||
// Id returns the Id as a string.
|
||||
func (i SimpleId) Id() string {
|
||||
return string(i)
|
||||
}
|
||||
|
||||
// SetId is a no-op
|
||||
func (i SimpleId) SetId(s string) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
// Name returns the Id
|
||||
func (i SimpleId) Name() string {
|
||||
return i.Id()
|
||||
}
|
22
chat/message/logger.go
Normal file
22
chat/message/logger.go
Normal file
@ -0,0 +1,22 @@
|
||||
package message
|
||||
|
||||
import "io"
|
||||
import stdlog "log"
|
||||
|
||||
var logger *stdlog.Logger
|
||||
|
||||
func SetLogger(w io.Writer) {
|
||||
flags := stdlog.Flags()
|
||||
prefix := "[chat/message] "
|
||||
logger = stdlog.New(w, prefix, flags)
|
||||
}
|
||||
|
||||
type nullWriter struct{}
|
||||
|
||||
func (nullWriter) Write(data []byte) (int, error) {
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
SetLogger(nullWriter{})
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -245,7 +245,6 @@ type CommandMsg struct {
|
||||
*PublicMsg
|
||||
command string
|
||||
args []string
|
||||
room *Room
|
||||
}
|
||||
|
||||
func (m *CommandMsg) Command() string {
|
||||
@ -255,3 +254,7 @@ func (m *CommandMsg) Command() string {
|
||||
func (m *CommandMsg) Args() []string {
|
||||
return m.args
|
||||
}
|
||||
|
||||
func (m *CommandMsg) Body() string {
|
||||
return m.body
|
||||
}
|
@ -1,19 +1,7 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import "testing"
|
||||
|
||||
type testId string
|
||||
|
||||
func (i testId) Id() string {
|
||||
return string(i)
|
||||
}
|
||||
func (i testId) SetId(s string) {
|
||||
// no-op
|
||||
}
|
||||
func (i testId) Name() string {
|
||||
return i.Id()
|
||||
}
|
||||
|
||||
func TestMessage(t *testing.T) {
|
||||
var expected, actual string
|
||||
|
||||
@ -23,7 +11,7 @@ func TestMessage(t *testing.T) {
|
||||
t.Errorf("Got: `%s`; Expected: `%s`", actual, expected)
|
||||
}
|
||||
|
||||
u := NewUser(testId("foo"))
|
||||
u := NewUser(SimpleId("foo"))
|
||||
expected = "foo: hello"
|
||||
actual = NewPublicMsg("hello", u).String()
|
||||
if actual != expected {
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import (
|
||||
"reflect"
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import "fmt"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@ -15,13 +15,6 @@ const reHighlight = `\b(%s)\b`
|
||||
|
||||
var ErrUserClosed = errors.New("user closed")
|
||||
|
||||
// Identifier is an interface that can uniquely identify itself.
|
||||
type Identifier interface {
|
||||
Id() string
|
||||
SetId(string)
|
||||
Name() string
|
||||
}
|
||||
|
||||
// User definition, implemented set Item interface and io.Writer
|
||||
type User struct {
|
||||
Identifier
|
||||
@ -106,8 +99,8 @@ func (u *User) Consume(out io.Writer) {
|
||||
}
|
||||
|
||||
// Consume one message and stop, mostly for testing
|
||||
func (u *User) ConsumeOne(out io.Writer) {
|
||||
u.HandleMsg(<-u.msg, out)
|
||||
func (u *User) ConsumeChan() <-chan Message {
|
||||
return u.msg
|
||||
}
|
||||
|
||||
// SetHighlight sets the highlighting regular expression to match string.
|
@ -1,4 +1,4 @@
|
||||
package chat
|
||||
package message
|
||||
|
||||
import (
|
||||
"reflect"
|
50
chat/room.go
50
chat/room.go
@ -5,6 +5,8 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
)
|
||||
|
||||
const historyLen = 20
|
||||
@ -20,16 +22,16 @@ var ErrInvalidName = errors.New("invalid name")
|
||||
|
||||
// Member is a User with per-Room metadata attached to it.
|
||||
type Member struct {
|
||||
*User
|
||||
*message.User
|
||||
Op bool
|
||||
}
|
||||
|
||||
// Room definition, also a Set of User Items
|
||||
type Room struct {
|
||||
topic string
|
||||
history *History
|
||||
history *message.History
|
||||
members *Set
|
||||
broadcast chan Message
|
||||
broadcast chan message.Message
|
||||
commands Commands
|
||||
closed bool
|
||||
closeOnce sync.Once
|
||||
@ -37,11 +39,11 @@ type Room struct {
|
||||
|
||||
// NewRoom creates a new room.
|
||||
func NewRoom() *Room {
|
||||
broadcast := make(chan Message, roomBuffer)
|
||||
broadcast := make(chan message.Message, roomBuffer)
|
||||
|
||||
return &Room{
|
||||
broadcast: broadcast,
|
||||
history: NewHistory(historyLen),
|
||||
history: message.NewHistory(historyLen),
|
||||
members: NewSet(),
|
||||
commands: *defaultCommands,
|
||||
}
|
||||
@ -56,7 +58,7 @@ func (r *Room) SetCommands(commands Commands) {
|
||||
func (r *Room) Close() {
|
||||
r.closeOnce.Do(func() {
|
||||
r.closed = true
|
||||
r.members.Each(func(m Identifier) {
|
||||
r.members.Each(func(m Item) {
|
||||
m.(*Member).Close()
|
||||
})
|
||||
r.members.Clear()
|
||||
@ -70,33 +72,33 @@ func (r *Room) SetLogging(out io.Writer) {
|
||||
}
|
||||
|
||||
// HandleMsg reacts to a message, will block until done.
|
||||
func (r *Room) HandleMsg(m Message) {
|
||||
func (r *Room) HandleMsg(m message.Message) {
|
||||
switch m := m.(type) {
|
||||
case *CommandMsg:
|
||||
case *message.CommandMsg:
|
||||
cmd := *m
|
||||
err := r.commands.Run(r, cmd)
|
||||
if err != nil {
|
||||
m := NewSystemMsg(fmt.Sprintf("Err: %s", err), cmd.from)
|
||||
m := message.NewSystemMsg(fmt.Sprintf("Err: %s", err), cmd.From())
|
||||
go r.HandleMsg(m)
|
||||
}
|
||||
case MessageTo:
|
||||
case message.MessageTo:
|
||||
user := m.To()
|
||||
user.Send(m)
|
||||
default:
|
||||
fromMsg, skip := m.(MessageFrom)
|
||||
var skipUser *User
|
||||
fromMsg, skip := m.(message.MessageFrom)
|
||||
var skipUser *message.User
|
||||
if skip {
|
||||
skipUser = fromMsg.From()
|
||||
}
|
||||
|
||||
r.history.Add(m)
|
||||
r.members.Each(func(u Identifier) {
|
||||
r.members.Each(func(u Item) {
|
||||
user := u.(*Member).User
|
||||
if skip && skipUser == user {
|
||||
// Skip
|
||||
return
|
||||
}
|
||||
if _, ok := m.(*AnnounceMsg); ok {
|
||||
if _, ok := m.(*message.AnnounceMsg); ok {
|
||||
if user.Config.Quiet {
|
||||
// Skip
|
||||
return
|
||||
@ -116,19 +118,19 @@ func (r *Room) Serve() {
|
||||
}
|
||||
|
||||
// Send message, buffered by a chan.
|
||||
func (r *Room) Send(m Message) {
|
||||
func (r *Room) Send(m message.Message) {
|
||||
r.broadcast <- m
|
||||
}
|
||||
|
||||
// History feeds the room's recent message history to the user's handler.
|
||||
func (r *Room) History(u *User) {
|
||||
func (r *Room) History(u *message.User) {
|
||||
for _, m := range r.history.Get(historyLen) {
|
||||
u.Send(m)
|
||||
}
|
||||
}
|
||||
|
||||
// Join the room as a user, will announce.
|
||||
func (r *Room) Join(u *User) (*Member, error) {
|
||||
func (r *Room) Join(u *message.User) (*Member, error) {
|
||||
if r.closed {
|
||||
return nil, ErrRoomClosed
|
||||
}
|
||||
@ -142,23 +144,23 @@ func (r *Room) Join(u *User) (*Member, error) {
|
||||
}
|
||||
r.History(u)
|
||||
s := fmt.Sprintf("%s joined. (Connected: %d)", u.Name(), r.members.Len())
|
||||
r.Send(NewAnnounceMsg(s))
|
||||
r.Send(message.NewAnnounceMsg(s))
|
||||
return &member, nil
|
||||
}
|
||||
|
||||
// Leave the room as a user, will announce. Mostly used during setup.
|
||||
func (r *Room) Leave(u *User) error {
|
||||
func (r *Room) Leave(u message.Identifier) error {
|
||||
err := r.members.Remove(u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s := fmt.Sprintf("%s left.", u.Name())
|
||||
r.Send(NewAnnounceMsg(s))
|
||||
r.Send(message.NewAnnounceMsg(s))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Rename member with a new identity. This will not call rename on the member.
|
||||
func (r *Room) Rename(oldId string, identity Identifier) error {
|
||||
func (r *Room) Rename(oldId string, identity message.Identifier) error {
|
||||
if identity.Id() == "" {
|
||||
return ErrInvalidName
|
||||
}
|
||||
@ -168,13 +170,13 @@ func (r *Room) Rename(oldId string, identity Identifier) error {
|
||||
}
|
||||
|
||||
s := fmt.Sprintf("%s is now known as %s.", oldId, identity.Id())
|
||||
r.Send(NewAnnounceMsg(s))
|
||||
r.Send(message.NewAnnounceMsg(s))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Member returns a corresponding Member object to a User if the Member is
|
||||
// present in this room.
|
||||
func (r *Room) Member(u *User) (*Member, bool) {
|
||||
func (r *Room) Member(u *message.User) (*Member, bool) {
|
||||
m, ok := r.MemberById(u.Id())
|
||||
if !ok {
|
||||
return nil, false
|
||||
@ -195,7 +197,7 @@ func (r *Room) MemberById(id string) (*Member, bool) {
|
||||
}
|
||||
|
||||
// IsOp returns whether a user is an operator in this room.
|
||||
func (r *Room) IsOp(u *User) bool {
|
||||
func (r *Room) IsOp(u *message.User) bool {
|
||||
m, ok := r.Member(u)
|
||||
return ok && m.Op
|
||||
}
|
||||
|
@ -3,11 +3,29 @@ package chat
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
)
|
||||
|
||||
// Used for testing
|
||||
type MockScreen struct {
|
||||
buffer []byte
|
||||
}
|
||||
|
||||
func (s *MockScreen) Write(data []byte) (n int, err error) {
|
||||
s.buffer = append(s.buffer, data...)
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
func (s *MockScreen) Read(p *[]byte) (n int, err error) {
|
||||
*p = s.buffer
|
||||
s.buffer = []byte{}
|
||||
return len(*p), nil
|
||||
}
|
||||
|
||||
func TestRoomServe(t *testing.T) {
|
||||
ch := NewRoom()
|
||||
ch.Send(NewAnnounceMsg("hello"))
|
||||
ch.Send(message.NewAnnounceMsg("hello"))
|
||||
|
||||
received := <-ch.broadcast
|
||||
actual := received.String()
|
||||
@ -22,7 +40,7 @@ func TestRoomJoin(t *testing.T) {
|
||||
var expected, actual []byte
|
||||
|
||||
s := &MockScreen{}
|
||||
u := NewUser(testId("foo"))
|
||||
u := message.NewUser(message.SimpleId("foo"))
|
||||
|
||||
ch := NewRoom()
|
||||
go ch.Serve()
|
||||
@ -33,24 +51,24 @@ func TestRoomJoin(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
u.ConsumeOne(s)
|
||||
expected = []byte(" * foo joined. (Connected: 1)" + Newline)
|
||||
u.HandleMsg(<-u.ConsumeChan(), s)
|
||||
expected = []byte(" * foo joined. (Connected: 1)" + message.Newline)
|
||||
s.Read(&actual)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Got: `%s`; Expected: `%s`", actual, expected)
|
||||
}
|
||||
|
||||
ch.Send(NewSystemMsg("hello", u))
|
||||
u.ConsumeOne(s)
|
||||
expected = []byte("-> hello" + Newline)
|
||||
ch.Send(message.NewSystemMsg("hello", u))
|
||||
u.HandleMsg(<-u.ConsumeChan(), s)
|
||||
expected = []byte("-> hello" + message.Newline)
|
||||
s.Read(&actual)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Got: `%s`; Expected: `%s`", actual, expected)
|
||||
}
|
||||
|
||||
ch.Send(ParseInput("/me says hello.", u))
|
||||
u.ConsumeOne(s)
|
||||
expected = []byte("** foo says hello." + Newline)
|
||||
ch.Send(message.ParseInput("/me says hello.", u))
|
||||
u.HandleMsg(<-u.ConsumeChan(), s)
|
||||
expected = []byte("** foo says hello." + message.Newline)
|
||||
s.Read(&actual)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Got: `%s`; Expected: `%s`", actual, expected)
|
||||
@ -58,8 +76,8 @@ func TestRoomJoin(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestRoomDoesntBroadcastAnnounceMessagesWhenQuiet(t *testing.T) {
|
||||
u := NewUser(testId("foo"))
|
||||
u.Config = UserConfig{
|
||||
u := message.NewUser(message.SimpleId("foo"))
|
||||
u.Config = message.UserConfig{
|
||||
Quiet: true,
|
||||
}
|
||||
|
||||
@ -75,8 +93,8 @@ func TestRoomDoesntBroadcastAnnounceMessagesWhenQuiet(t *testing.T) {
|
||||
<-ch.broadcast
|
||||
|
||||
go func() {
|
||||
for msg := range u.msg {
|
||||
if _, ok := msg.(*AnnounceMsg); ok {
|
||||
for msg := range u.ConsumeChan() {
|
||||
if _, ok := msg.(*message.AnnounceMsg); ok {
|
||||
t.Errorf("Got unexpected `%T`", msg)
|
||||
}
|
||||
}
|
||||
@ -84,17 +102,17 @@ func TestRoomDoesntBroadcastAnnounceMessagesWhenQuiet(t *testing.T) {
|
||||
|
||||
// Call with an AnnounceMsg and all the other types
|
||||
// and assert we received only non-announce messages
|
||||
ch.HandleMsg(NewAnnounceMsg("Ignored"))
|
||||
ch.HandleMsg(message.NewAnnounceMsg("Ignored"))
|
||||
// Assert we still get all other types of messages
|
||||
ch.HandleMsg(NewEmoteMsg("hello", u))
|
||||
ch.HandleMsg(NewSystemMsg("hello", u))
|
||||
ch.HandleMsg(NewPrivateMsg("hello", u, u))
|
||||
ch.HandleMsg(NewPublicMsg("hello", u))
|
||||
ch.HandleMsg(message.NewEmoteMsg("hello", u))
|
||||
ch.HandleMsg(message.NewSystemMsg("hello", u))
|
||||
ch.HandleMsg(message.NewPrivateMsg("hello", u, u))
|
||||
ch.HandleMsg(message.NewPublicMsg("hello", u))
|
||||
}
|
||||
|
||||
func TestRoomQuietToggleBroadcasts(t *testing.T) {
|
||||
u := NewUser(testId("foo"))
|
||||
u.Config = UserConfig{
|
||||
u := message.NewUser(message.SimpleId("foo"))
|
||||
u.Config = message.UserConfig{
|
||||
Quiet: true,
|
||||
}
|
||||
|
||||
@ -111,19 +129,19 @@ func TestRoomQuietToggleBroadcasts(t *testing.T) {
|
||||
|
||||
u.ToggleQuietMode()
|
||||
|
||||
expectedMsg := NewAnnounceMsg("Ignored")
|
||||
expectedMsg := message.NewAnnounceMsg("Ignored")
|
||||
ch.HandleMsg(expectedMsg)
|
||||
msg := <-u.msg
|
||||
if _, ok := msg.(*AnnounceMsg); !ok {
|
||||
msg := <-u.ConsumeChan()
|
||||
if _, ok := msg.(*message.AnnounceMsg); !ok {
|
||||
t.Errorf("Got: `%T`; Expected: `%T`", msg, expectedMsg)
|
||||
}
|
||||
|
||||
u.ToggleQuietMode()
|
||||
|
||||
ch.HandleMsg(NewAnnounceMsg("Ignored"))
|
||||
ch.HandleMsg(NewSystemMsg("hello", u))
|
||||
msg = <-u.msg
|
||||
if _, ok := msg.(*AnnounceMsg); ok {
|
||||
ch.HandleMsg(message.NewAnnounceMsg("Ignored"))
|
||||
ch.HandleMsg(message.NewSystemMsg("hello", u))
|
||||
msg = <-u.ConsumeChan()
|
||||
if _, ok := msg.(*message.AnnounceMsg); ok {
|
||||
t.Errorf("Got unexpected `%T`", msg)
|
||||
}
|
||||
}
|
||||
@ -132,7 +150,7 @@ func TestQuietToggleDisplayState(t *testing.T) {
|
||||
var expected, actual []byte
|
||||
|
||||
s := &MockScreen{}
|
||||
u := NewUser(testId("foo"))
|
||||
u := message.NewUser(message.SimpleId("foo"))
|
||||
|
||||
ch := NewRoom()
|
||||
go ch.Serve()
|
||||
@ -146,17 +164,17 @@ func TestQuietToggleDisplayState(t *testing.T) {
|
||||
// Drain the initial Join message
|
||||
<-ch.broadcast
|
||||
|
||||
ch.Send(ParseInput("/quiet", u))
|
||||
u.ConsumeOne(s)
|
||||
expected = []byte("-> Quiet mode is toggled ON" + Newline)
|
||||
ch.Send(message.ParseInput("/quiet", u))
|
||||
u.HandleMsg(<-u.ConsumeChan(), s)
|
||||
expected = []byte("-> Quiet mode is toggled ON" + message.Newline)
|
||||
s.Read(&actual)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Got: `%s`; Expected: `%s`", actual, expected)
|
||||
}
|
||||
|
||||
ch.Send(ParseInput("/quiet", u))
|
||||
u.ConsumeOne(s)
|
||||
expected = []byte("-> Quiet mode is toggled OFF" + Newline)
|
||||
ch.Send(message.ParseInput("/quiet", u))
|
||||
u.HandleMsg(<-u.ConsumeChan(), s)
|
||||
expected = []byte("-> Quiet mode is toggled OFF" + message.Newline)
|
||||
|
||||
s.Read(&actual)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
@ -168,7 +186,7 @@ func TestRoomNames(t *testing.T) {
|
||||
var expected, actual []byte
|
||||
|
||||
s := &MockScreen{}
|
||||
u := NewUser(testId("foo"))
|
||||
u := message.NewUser(message.SimpleId("foo"))
|
||||
|
||||
ch := NewRoom()
|
||||
go ch.Serve()
|
||||
@ -182,9 +200,9 @@ func TestRoomNames(t *testing.T) {
|
||||
// Drain the initial Join message
|
||||
<-ch.broadcast
|
||||
|
||||
ch.Send(ParseInput("/names", u))
|
||||
u.ConsumeOne(s)
|
||||
expected = []byte("-> 1 connected: foo" + Newline)
|
||||
ch.Send(message.ParseInput("/names", u))
|
||||
u.HandleMsg(<-u.ConsumeChan(), s)
|
||||
expected = []byte("-> 1 connected: foo" + message.Newline)
|
||||
s.Read(&actual)
|
||||
if !reflect.DeepEqual(actual, expected) {
|
||||
t.Errorf("Got: `%s`; Expected: `%s`", actual, expected)
|
||||
|
33
chat/set.go
33
chat/set.go
@ -12,17 +12,22 @@ var ErrIdTaken = errors.New("id already taken")
|
||||
// The error returned when a requested item does not exist in the set.
|
||||
var ErrItemMissing = errors.New("item does not exist")
|
||||
|
||||
// Interface for an item storeable in the set
|
||||
type Item interface {
|
||||
Id() string
|
||||
}
|
||||
|
||||
// Set with string lookup.
|
||||
// TODO: Add trie for efficient prefix lookup?
|
||||
type Set struct {
|
||||
lookup map[string]Identifier
|
||||
lookup map[string]Item
|
||||
sync.RWMutex
|
||||
}
|
||||
|
||||
// NewSet creates a new set.
|
||||
func NewSet() *Set {
|
||||
return &Set{
|
||||
lookup: map[string]Identifier{},
|
||||
lookup: map[string]Item{},
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +35,7 @@ func NewSet() *Set {
|
||||
func (s *Set) Clear() int {
|
||||
s.Lock()
|
||||
n := len(s.lookup)
|
||||
s.lookup = map[string]Identifier{}
|
||||
s.lookup = map[string]Item{}
|
||||
s.Unlock()
|
||||
return n
|
||||
}
|
||||
@ -41,7 +46,7 @@ func (s *Set) Len() int {
|
||||
}
|
||||
|
||||
// In checks if an item exists in this set.
|
||||
func (s *Set) In(item Identifier) bool {
|
||||
func (s *Set) In(item Item) bool {
|
||||
s.RLock()
|
||||
_, ok := s.lookup[item.Id()]
|
||||
s.RUnlock()
|
||||
@ -49,7 +54,7 @@ func (s *Set) In(item Identifier) bool {
|
||||
}
|
||||
|
||||
// Get returns an item with the given Id.
|
||||
func (s *Set) Get(id string) (Identifier, error) {
|
||||
func (s *Set) Get(id string) (Item, error) {
|
||||
s.RLock()
|
||||
item, ok := s.lookup[id]
|
||||
s.RUnlock()
|
||||
@ -62,7 +67,7 @@ func (s *Set) Get(id string) (Identifier, error) {
|
||||
}
|
||||
|
||||
// Add item to this set if it does not exist already.
|
||||
func (s *Set) Add(item Identifier) error {
|
||||
func (s *Set) Add(item Item) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
@ -76,7 +81,7 @@ func (s *Set) Add(item Identifier) error {
|
||||
}
|
||||
|
||||
// Remove item from this set.
|
||||
func (s *Set) Remove(item Identifier) error {
|
||||
func (s *Set) Remove(item Item) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
id := item.Id()
|
||||
@ -88,9 +93,9 @@ func (s *Set) Remove(item Identifier) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Replace item from old id with new Identifier.
|
||||
// Used for moving the same identifier to a new Id, such as a rename.
|
||||
func (s *Set) Replace(oldId string, item Identifier) error {
|
||||
// Replace item from old id with new Item.
|
||||
// Used for moving the same Item to a new Id, such as a rename.
|
||||
func (s *Set) Replace(oldId string, item Item) error {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
@ -107,7 +112,7 @@ func (s *Set) Replace(oldId string, item Identifier) error {
|
||||
}
|
||||
delete(s.lookup, oldId)
|
||||
|
||||
// Add new identifier
|
||||
// Add new Item
|
||||
s.lookup[item.Id()] = item
|
||||
|
||||
return nil
|
||||
@ -115,7 +120,7 @@ func (s *Set) Replace(oldId string, item Identifier) error {
|
||||
|
||||
// Each loops over every item while holding a read lock and applies fn to each
|
||||
// element.
|
||||
func (s *Set) Each(fn func(item Identifier)) {
|
||||
func (s *Set) Each(fn func(item Item)) {
|
||||
s.RLock()
|
||||
for _, item := range s.lookup {
|
||||
fn(item)
|
||||
@ -124,8 +129,8 @@ func (s *Set) Each(fn func(item Identifier)) {
|
||||
}
|
||||
|
||||
// ListPrefix returns a list of items with a prefix, case insensitive.
|
||||
func (s *Set) ListPrefix(prefix string) []Identifier {
|
||||
r := []Identifier{}
|
||||
func (s *Set) ListPrefix(prefix string) []Item {
|
||||
r := []Item{}
|
||||
prefix = strings.ToLower(prefix)
|
||||
|
||||
s.RLock()
|
||||
|
@ -1,11 +1,15 @@
|
||||
package chat
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
)
|
||||
|
||||
func TestSet(t *testing.T) {
|
||||
var err error
|
||||
s := NewSet()
|
||||
u := NewUser(testId("foo"))
|
||||
u := message.NewUser(message.SimpleId("foo"))
|
||||
|
||||
if s.In(u) {
|
||||
t.Errorf("Set should be empty.")
|
||||
@ -20,7 +24,7 @@ func TestSet(t *testing.T) {
|
||||
t.Errorf("Set should contain user.")
|
||||
}
|
||||
|
||||
u2 := NewUser(testId("bar"))
|
||||
u2 := message.NewUser(message.SimpleId("bar"))
|
||||
err = s.Add(u2)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
|
3
cmd.go
3
cmd.go
@ -16,6 +16,7 @@ import (
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat"
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
"github.com/shazow/ssh-chat/sshd"
|
||||
)
|
||||
import _ "net/http/pprof"
|
||||
@ -109,7 +110,7 @@ func main() {
|
||||
|
||||
host := NewHost(s)
|
||||
host.auth = auth
|
||||
host.theme = &chat.Themes[0]
|
||||
host.theme = &message.Themes[0]
|
||||
|
||||
err = fromFile(options.Admin, func(line []byte) error {
|
||||
key, _, _, _, err := ssh.ParseAuthorizedKey(line)
|
||||
|
59
host.go
59
host.go
@ -9,13 +9,14 @@ import (
|
||||
|
||||
"github.com/shazow/rateio"
|
||||
"github.com/shazow/ssh-chat/chat"
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
"github.com/shazow/ssh-chat/sshd"
|
||||
)
|
||||
|
||||
const maxInputLength int = 1024
|
||||
|
||||
// GetPrompt will render the terminal prompt string based on the user.
|
||||
func GetPrompt(user *chat.User) string {
|
||||
func GetPrompt(user *message.User) string {
|
||||
name := user.Name()
|
||||
if user.Config.Theme != nil {
|
||||
name = user.Config.Theme.ColorName(user)
|
||||
@ -35,7 +36,7 @@ type Host struct {
|
||||
count int
|
||||
|
||||
// Default theme
|
||||
theme *chat.Theme
|
||||
theme *message.Theme
|
||||
}
|
||||
|
||||
// NewHost creates a Host on top of an existing listener.
|
||||
@ -72,7 +73,7 @@ func (h Host) isOp(conn sshd.Connection) bool {
|
||||
// Connect a specific Terminal to this host and its room.
|
||||
func (h *Host) Connect(term *sshd.Terminal) {
|
||||
id := NewIdentity(term.Conn)
|
||||
user := chat.NewUserScreen(id, term)
|
||||
user := message.NewUserScreen(id, term)
|
||||
user.Config.Theme = h.theme
|
||||
go func() {
|
||||
// Close term once user is closed.
|
||||
@ -83,7 +84,7 @@ func (h *Host) Connect(term *sshd.Terminal) {
|
||||
|
||||
// Send MOTD
|
||||
if h.motd != "" {
|
||||
user.Send(chat.NewAnnounceMsg(h.motd))
|
||||
user.Send(message.NewAnnounceMsg(h.motd))
|
||||
}
|
||||
|
||||
member, err := h.Join(user)
|
||||
@ -119,11 +120,11 @@ func (h *Host) Connect(term *sshd.Terminal) {
|
||||
|
||||
err = ratelimit.Count(1)
|
||||
if err != nil {
|
||||
user.Send(chat.NewSystemMsg("Message rejected: Rate limiting is in effect.", user))
|
||||
user.Send(message.NewSystemMsg("Message rejected: Rate limiting is in effect.", user))
|
||||
continue
|
||||
}
|
||||
if len(line) > maxInputLength {
|
||||
user.Send(chat.NewSystemMsg("Message rejected: Input too long.", user))
|
||||
user.Send(message.NewSystemMsg("Message rejected: Input too long.", user))
|
||||
continue
|
||||
}
|
||||
if line == "" {
|
||||
@ -131,7 +132,7 @@ func (h *Host) Connect(term *sshd.Terminal) {
|
||||
continue
|
||||
}
|
||||
|
||||
m := chat.ParseInput(line, user)
|
||||
m := message.ParseInput(line, user)
|
||||
|
||||
// FIXME: Any reason to use h.room.Send(m) instead?
|
||||
h.HandleMsg(m)
|
||||
@ -184,7 +185,7 @@ func (h Host) completeCommand(partial string) string {
|
||||
}
|
||||
|
||||
// AutoCompleteFunction returns a callback for terminal autocompletion
|
||||
func (h *Host) AutoCompleteFunction(u *chat.User) func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
|
||||
func (h *Host) AutoCompleteFunction(u *message.User) func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
|
||||
return func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
|
||||
if key != 9 {
|
||||
return
|
||||
@ -231,8 +232,8 @@ func (h *Host) AutoCompleteFunction(u *chat.User) func(line string, pos int, key
|
||||
}
|
||||
}
|
||||
|
||||
// GetUser returns a chat.User based on a name.
|
||||
func (h *Host) GetUser(name string) (*chat.User, bool) {
|
||||
// GetUser returns a message.User based on a name.
|
||||
func (h *Host) GetUser(name string) (*message.User, bool) {
|
||||
m, ok := h.MemberById(name)
|
||||
if !ok {
|
||||
return nil, false
|
||||
@ -247,7 +248,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
Prefix: "/msg",
|
||||
PrefixHelp: "USER MESSAGE",
|
||||
Help: "Send MESSAGE to USER.",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
args := msg.Args()
|
||||
switch len(args) {
|
||||
case 0:
|
||||
@ -261,7 +262,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
return errors.New("user not found")
|
||||
}
|
||||
|
||||
m := chat.NewPrivateMsg(strings.Join(args[1:], " "), msg.From(), target)
|
||||
m := message.NewPrivateMsg(strings.Join(args[1:], " "), msg.From(), target)
|
||||
room.Send(m)
|
||||
return nil
|
||||
},
|
||||
@ -271,7 +272,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
Prefix: "/reply",
|
||||
PrefixHelp: "MESSAGE",
|
||||
Help: "Reply with MESSAGE to the previous private message.",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
args := msg.Args()
|
||||
switch len(args) {
|
||||
case 0:
|
||||
@ -283,7 +284,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
return errors.New("no message to reply to")
|
||||
}
|
||||
|
||||
m := chat.NewPrivateMsg(strings.Join(args, " "), msg.From(), target)
|
||||
m := message.NewPrivateMsg(strings.Join(args, " "), msg.From(), target)
|
||||
room.Send(m)
|
||||
return nil
|
||||
},
|
||||
@ -293,7 +294,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
Prefix: "/whois",
|
||||
PrefixHelp: "USER",
|
||||
Help: "Information about USER.",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
args := msg.Args()
|
||||
if len(args) == 0 {
|
||||
return errors.New("must specify user")
|
||||
@ -305,7 +306,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
}
|
||||
|
||||
id := target.Identifier.(*Identity)
|
||||
room.Send(chat.NewSystemMsg(id.Whois(), msg.From()))
|
||||
room.Send(message.NewSystemMsg(id.Whois(), msg.From()))
|
||||
|
||||
return nil
|
||||
},
|
||||
@ -314,8 +315,8 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
// Hidden commands
|
||||
c.Add(chat.Command{
|
||||
Prefix: "/version",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
room.Send(chat.NewSystemMsg(buildCommit, msg.From()))
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
room.Send(message.NewSystemMsg(buildCommit, msg.From()))
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@ -323,8 +324,8 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
timeStarted := time.Now()
|
||||
c.Add(chat.Command{
|
||||
Prefix: "/uptime",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
room.Send(chat.NewSystemMsg(time.Now().Sub(timeStarted).String(), msg.From()))
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
room.Send(message.NewSystemMsg(time.Now().Sub(timeStarted).String(), msg.From()))
|
||||
return nil
|
||||
},
|
||||
})
|
||||
@ -335,7 +336,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
Prefix: "/kick",
|
||||
PrefixHelp: "USER",
|
||||
Help: "Kick USER from the server.",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
if !room.IsOp(msg.From()) {
|
||||
return errors.New("must be op")
|
||||
}
|
||||
@ -351,7 +352,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
}
|
||||
|
||||
body := fmt.Sprintf("%s was kicked by %s.", target.Name(), msg.From().Name())
|
||||
room.Send(chat.NewAnnounceMsg(body))
|
||||
room.Send(message.NewAnnounceMsg(body))
|
||||
target.Close()
|
||||
return nil
|
||||
},
|
||||
@ -362,7 +363,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
Prefix: "/ban",
|
||||
PrefixHelp: "USER [DURATION]",
|
||||
Help: "Ban USER from the server.",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
// TODO: Would be nice to specify what to ban. Key? Ip? etc.
|
||||
if !room.IsOp(msg.From()) {
|
||||
return errors.New("must be op")
|
||||
@ -388,7 +389,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
h.auth.BanAddr(id.RemoteAddr(), until)
|
||||
|
||||
body := fmt.Sprintf("%s was banned by %s.", target.Name(), msg.From().Name())
|
||||
room.Send(chat.NewAnnounceMsg(body))
|
||||
room.Send(message.NewAnnounceMsg(body))
|
||||
target.Close()
|
||||
|
||||
logger.Debugf("Banned: \n-> %s", id.Whois())
|
||||
@ -402,7 +403,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
Prefix: "/motd",
|
||||
PrefixHelp: "MESSAGE",
|
||||
Help: "Set the MESSAGE of the day.",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
if !room.IsOp(msg.From()) {
|
||||
return errors.New("must be op")
|
||||
}
|
||||
@ -415,9 +416,9 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
|
||||
h.motd = motd
|
||||
body := fmt.Sprintf("New message of the day set by %s:", msg.From().Name())
|
||||
room.Send(chat.NewAnnounceMsg(body))
|
||||
room.Send(message.NewAnnounceMsg(body))
|
||||
if motd != "" {
|
||||
room.Send(chat.NewAnnounceMsg(motd))
|
||||
room.Send(message.NewAnnounceMsg(motd))
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -429,7 +430,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
Prefix: "/op",
|
||||
PrefixHelp: "USER [DURATION]",
|
||||
Help: "Set USER as admin.",
|
||||
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
|
||||
Handler: func(room *chat.Room, msg message.CommandMsg) error {
|
||||
if !room.IsOp(msg.From()) {
|
||||
return errors.New("must be op")
|
||||
}
|
||||
@ -453,7 +454,7 @@ func (h *Host) InitCommands(c *chat.Commands) {
|
||||
h.auth.Op(id.PublicKey(), until)
|
||||
|
||||
body := fmt.Sprintf("Made op by %s.", msg.From().Name())
|
||||
room.Send(chat.NewSystemMsg(body, member.User))
|
||||
room.Send(message.NewSystemMsg(body, member.User))
|
||||
|
||||
return nil
|
||||
},
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat"
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
"github.com/shazow/ssh-chat/sshd"
|
||||
"golang.org/x/crypto/ssh"
|
||||
)
|
||||
@ -26,7 +26,7 @@ func stripPrompt(s string) string {
|
||||
func TestHostGetPrompt(t *testing.T) {
|
||||
var expected, actual string
|
||||
|
||||
u := chat.NewUser(&Identity{nil, "foo"})
|
||||
u := message.NewUser(&Identity{nil, "foo"})
|
||||
u.SetColorIdx(2)
|
||||
|
||||
actual = GetPrompt(u)
|
||||
@ -35,7 +35,7 @@ func TestHostGetPrompt(t *testing.T) {
|
||||
t.Errorf("Got: %q; Expected: %q", actual, expected)
|
||||
}
|
||||
|
||||
u.Config.Theme = &chat.Themes[0]
|
||||
u.Config.Theme = &message.Themes[0]
|
||||
actual = GetPrompt(u)
|
||||
expected = "[\033[38;05;2mfoo\033[0m] "
|
||||
if actual != expected {
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"net"
|
||||
|
||||
"github.com/shazow/ssh-chat/chat"
|
||||
"github.com/shazow/ssh-chat/chat/message"
|
||||
"github.com/shazow/ssh-chat/sshd"
|
||||
)
|
||||
|
||||
@ -44,7 +45,7 @@ func (i Identity) Whois() string {
|
||||
if i.PublicKey() != nil {
|
||||
fingerprint = sshd.Fingerprint(i.PublicKey())
|
||||
}
|
||||
return fmt.Sprintf("name: %s"+chat.Newline+
|
||||
" > ip: %s"+chat.Newline+
|
||||
return fmt.Sprintf("name: %s"+message.Newline+
|
||||
" > ip: %s"+message.Newline+
|
||||
" > fingerprint: %s", i.Name(), ip, fingerprint)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user