From 40bf20405848c7cd13764f3b987eba7d1bc05eb8 Mon Sep 17 00:00:00 2001 From: Robert Hailey Date: Wed, 2 Jan 2019 14:46:21 -0600 Subject: [PATCH] chat: When a user leaves, add time since they joined to the exit message. * Show the connection duration upon departure * humantime: ugly sub-second precision replaces grammatically incorrect "1 seconds" message * simplify function name * humantime: repair unit test * move: util/humantime -> internal/humantime * go fmt everything --- chat/message/user.go | 4 ++++ chat/room.go | 5 +++-- host.go | 3 ++- identity.go | 5 +++-- humantime.go => internal/humantime/humantime.go | 8 ++++++-- humantime_test.go => internal/humantime/humantime_test.go | 5 +++-- 6 files changed, 21 insertions(+), 9 deletions(-) rename humantime.go => internal/humantime/humantime.go (68%) rename humantime_test.go => internal/humantime/humantime_test.go (76%) diff --git a/chat/message/user.go b/chat/message/user.go index cc12ebc..d094bde 100644 --- a/chat/message/user.go +++ b/chat/message/user.go @@ -59,6 +59,10 @@ func NewUserScreen(identity Identifier, screen io.WriteCloser) *User { return u } +func (u *User) Joined() time.Time { + return u.joined +} + func (u *User) Config() UserConfig { u.mu.Lock() defer u.mu.Unlock() diff --git a/chat/room.go b/chat/room.go index 7ce6de1..96a1a35 100644 --- a/chat/room.go +++ b/chat/room.go @@ -7,6 +7,7 @@ import ( "sync" "github.com/shazow/ssh-chat/chat/message" + "github.com/shazow/ssh-chat/internal/humantime" "github.com/shazow/ssh-chat/set" ) @@ -159,13 +160,13 @@ func (r *Room) Join(u *message.User) (*Member, error) { } // Leave the room as a user, will announce. Mostly used during setup. -func (r *Room) Leave(u message.Identifier) error { +func (r *Room) Leave(u *message.User) error { err := r.Members.Remove(u.ID()) if err != nil { return err } r.Ops.Remove(u.ID()) - s := fmt.Sprintf("%s left.", u.Name()) + s := fmt.Sprintf("%s left. (Connected %s)", u.Name(), humantime.Since(u.Joined())) r.Send(message.NewAnnounceMsg(s)) return nil } diff --git a/host.go b/host.go index c4541ee..05ecaa0 100644 --- a/host.go +++ b/host.go @@ -12,6 +12,7 @@ import ( "github.com/shazow/rateio" "github.com/shazow/ssh-chat/chat" "github.com/shazow/ssh-chat/chat/message" + "github.com/shazow/ssh-chat/internal/humantime" "github.com/shazow/ssh-chat/set" "github.com/shazow/ssh-chat/sshd" ) @@ -382,7 +383,7 @@ func (h *Host) InitCommands(c *chat.Commands) { c.Add(chat.Command{ Prefix: "/uptime", Handler: func(room *chat.Room, msg message.CommandMsg) error { - room.Send(message.NewSystemMsg(humanSince(time.Since(timeStarted)), msg.From())) + room.Send(message.NewSystemMsg(humantime.Since(timeStarted), msg.From())) return nil }, }) diff --git a/identity.go b/identity.go index 6d620bf..05d754f 100644 --- a/identity.go +++ b/identity.go @@ -5,6 +5,7 @@ import ( "time" "github.com/shazow/ssh-chat/chat/message" + "github.com/shazow/ssh-chat/internal/humantime" "github.com/shazow/ssh-chat/internal/sanitize" "github.com/shazow/ssh-chat/sshd" ) @@ -50,7 +51,7 @@ func (i Identity) Whois() string { return "name: " + i.Name() + message.Newline + " > fingerprint: " + fingerprint + message.Newline + " > client: " + sanitize.Data(string(i.ClientVersion()), 64) + message.Newline + - " > joined: " + humanSince(time.Since(i.created)) + " ago" + " > joined: " + humantime.Since(i.created) + " ago" } // WhoisAdmin returns a whois description for admin users. @@ -64,5 +65,5 @@ func (i Identity) WhoisAdmin() string { " > ip: " + ip + message.Newline + " > fingerprint: " + fingerprint + message.Newline + " > client: " + sanitize.Data(string(i.ClientVersion()), 64) + message.Newline + - " > joined: " + humanSince(time.Since(i.created)) + " ago" + " > joined: " + humantime.Since(i.created) + " ago" } diff --git a/humantime.go b/internal/humantime/humantime.go similarity index 68% rename from humantime.go rename to internal/humantime/humantime.go index 4b361f9..8c28d84 100644 --- a/humantime.go +++ b/internal/humantime/humantime.go @@ -1,4 +1,4 @@ -package sshchat +package humantime import ( "fmt" @@ -6,8 +6,12 @@ import ( ) // humanSince returns a human-friendly relative time string -func humanSince(d time.Duration) string { +func Since(t time.Time) string { + d := time.Since(t) switch { + case d < time.Second*2: + //e.g. "516.971µs", "535.412009ms", "1.880689686s" + return d.String() case d < time.Minute*2: return fmt.Sprintf("%0.f seconds", d.Seconds()) case d < time.Hour*2: diff --git a/humantime_test.go b/internal/humantime/humantime_test.go similarity index 76% rename from humantime_test.go rename to internal/humantime/humantime_test.go index ca6c929..d5f14cd 100644 --- a/humantime_test.go +++ b/internal/humantime/humantime_test.go @@ -1,4 +1,4 @@ -package sshchat +package humantime import ( "testing" @@ -33,7 +33,8 @@ func TestHumanSince(t *testing.T) { } for _, test := range tests { - if actual, expected := humanSince(test.input), test.expected; actual != expected { + absolute := time.Now().Add(test.input * -1) + if actual, expected := Since(absolute), test.expected; actual != expected { t.Errorf("Got: %q; Expected: %q", actual, expected) } }