/
stats.go
117 lines (107 loc) · 3.03 KB
/
stats.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package commands
import (
"bytes"
"fmt"
"time"
"github.com/Depado/fox/acl"
"github.com/Depado/fox/message"
"github.com/Depado/fox/player"
"github.com/bwmarrin/discordgo"
"github.com/rs/zerolog"
"github.com/wcharczuk/go-chart"
)
type stats struct {
BaseCommand
}
func (c *stats) Handler(s *discordgo.Session, m *discordgo.Message, args []string) {
p := c.Players.GetPlayer(m.GuildID)
if p == nil {
c.log.Error().Msg("no player associated to guild ID")
return
}
if p.Stats == nil {
message.SendShortTimedNotice(s, m, "There is no encoding session", c.log)
return
}
p.Stats.RLock()
e := &discordgo.MessageEmbed{
Title: "📈 Stream & encoding stats",
Color: 0xff5500,
Fields: []*discordgo.MessageEmbedField{
{Name: "Playback", Value: p.Stats.PlaybackPosition.String(), Inline: true},
{Name: "Encoded", Value: p.Stats.Duration.String(), Inline: true},
{Name: "Size", Value: fmt.Sprintf("%5d kB", p.Stats.Size), Inline: true},
{Name: "Bitrate", Value: fmt.Sprintf("%6.2f kB/s", p.Stats.Bitrate), Inline: true},
{Name: "Speed", Value: fmt.Sprintf("%5.1fx", p.Stats.Speed), Inline: true},
},
}
p.Stats.RUnlock()
msg := &discordgo.MessageSend{
Embed: e,
}
if len(args) > 0 {
switch args[0] {
case "chart", "c", "graph", "g":
g := p.Stats.GenerateChart()
if g != nil {
buffer := bytes.NewBuffer([]byte{})
if err := g.Render(chart.PNG, buffer); err != nil {
c.log.Err(err).Msg("unable to render")
} else {
msg.File = &discordgo.File{
Name: "graph.png",
ContentType: "image/png",
Reader: buffer,
}
}
}
}
}
mess, err := s.ChannelMessageSendComplex(m.ChannelID, msg)
if err != nil {
c.log.Err(err).Msg("unable to send embed")
}
go func() {
time.Sleep(30 * time.Second)
if err := s.ChannelMessageDelete(mess.ChannelID, mess.ID); err != nil {
c.log.Err(err).Msg("unable to delete stats message")
}
}()
}
func NewStatsCommand(p *player.Players, log zerolog.Logger) Command {
cmd := "stats"
return &stats{
BaseCommand{
ChannelRestriction: acl.Music,
RoleRestriction: acl.Privileged,
Options: Options{
ArgsRequired: false,
DeleteUserMessage: true,
},
Long: cmd,
Aliases: []string{"s"},
SubCommands: []SubCommand{
{
Long: "graph",
Aliases: []string{"chart", "c", "g"},
Description: "Display an additional graph for kB/s",
},
},
Help: Help{
Usage: cmd,
ShortDesc: "View encoding and streaming instant stats",
Description: "This command will display the encoding and " +
"streaming stats if a stream is ongoing. Using the graph " +
"subcommand will also display a graph of the bitrate over " +
"the whole encoding session.",
Examples: []Example{
{Command: "stats", Explanation: "Display instant stats"},
{Command: "stats graph", Explanation: "Display instant stats and graph"},
{Command: "stats g", Explanation: "Same in short notation"},
},
},
Players: p,
log: log.With().Str("command", cmd).Logger(),
},
}
}