package main import ( "fmt" "net/http" "strings" ) /* * General Message Processor */ type generalProcessor struct{} func (p *generalProcessor) GetName() string { return "stat_bot General Processor" } func (p *generalProcessor) GetHelp() string { return "" } func (p *generalProcessor) ProcessMessage(slack *Slack, m *Message) {} func (p *generalProcessor) ProcessBotMessage(slack *Slack, m *Message) {} func (p *generalProcessor) ProcessAdminMessage(slack *Slack, m *Message) {} func (p *generalProcessor) ProcessUserMessage(slack *Slack, m *Message) {} func (p *generalProcessor) ProcessAdminUserMessage(slack *Slack, m *Message) { // Check if we were mentioned if strings.HasPrefix(m.Text, "<@"+slack.id+">") { parts := strings.Fields(m.Text) var action, target string if len(parts) >= 2 { action = parts[1] if len(parts) >= 3 { target = parts[2] } } if action == "mkadmin" && target != "" { // Make a user an admin if strings.HasPrefix(target, "<@") && strings.HasSuffix(target, ">") { target = strings.Trim(target, "<@>") if e := addAdmin(target); e == nil { m.Text = "User <@" + target + "> has been made an admin" } else { m.Text = fmt.Sprintf("%s", e) } } else { m.Text = "Please specify an existing user starting with a '@'" } slack.postMessage(*m) } else if action == "rmadmin" && target != "" { // Revoke a user as an admin if strings.HasPrefix(target, "<@") && strings.HasSuffix(target, ">") { target = strings.Trim(target, "<@>") if e := removeAdmin(target); e == nil { m.Text = "Admin privileges revoked from <@" + target + ">" } else { m.Text = fmt.Sprintf("%s", e) } } else { m.Text = "Please specify an existing user starting with a '@'" } slack.postMessage(*m) } else { // huh? m.Text = fmt.Sprintf("Beep boop beep, that does not compute\n") slack.postMessage(*m) } } } func (p *generalProcessor) ProcessBotUserMessage(slack *Slack, m *Message) {} func (p *generalProcessor) ProcessChannelMessage(slack *Slack, m *Message) {} func (p *generalProcessor) ProcessAdminChannelMessage(slack *Slack, m *Message) {} func (p *generalProcessor) ProcessBotChannelMessage(slack *Slack, m *Message) {} /* *General Statistics Processor */ type generalStatProcessor struct{} func (p *generalStatProcessor) GetName() string { return "General Statistics" } func (p *generalStatProcessor) GetStatKeys() []string { return []string{ "bot-message", "channel-message", "message-hour-*", "message-dow-*", "message-dom-*", } } func (p *generalStatProcessor) ProcessMessage(m *Message) { incrementUserStat(m.User, "message-hour-"+m.Time.Format("15")) incrementUserStat(m.User, "message-dow-"+m.Time.Format("Mon")) incrementUserStat(m.User, "message-dom-"+m.Time.Format("02")) } func (p *generalStatProcessor) ProcessBotMessage(m *Message) {} func (p *generalStatProcessor) ProcessUserMessage(m *Message) { incrementUserStat(m.User, "bot-message") } func (p *generalStatProcessor) ProcessBotUserMessage(m *Message) {} func (p *generalStatProcessor) ProcessChannelMessage(m *Message) { incrementUserStat(m.User, "channel-message") incrementChannelStat(m.Channel, "message-hour-"+m.Time.Format("15")) incrementChannelStat(m.Channel, "message-dow-"+m.Time.Format("Mon")) incrementChannelStat(m.Channel, "message-dom-"+m.Time.Format("02")) } func (p *generalStatProcessor) ProcessBotChannelMessage(m *Message) {} /* * Web Site Module */ type generalWebModule struct{} func (wm *generalWebModule) GetName() string { return "General Web Module" } func (wm *generalWebModule) GetRoutes() map[string]func(http.ResponseWriter, *http.Request) { ret := make(map[string]func(http.ResponseWriter, *http.Request)) ret["/"] = wm.handleStats return ret } func (wm *generalWebModule) Register() { for k, v := range wm.GetRoutes() { r.HandleFunc(k, v) } } func (wm *generalWebModule) GetMenuEntries() []menuItem { var ret []menuItem ret = append(ret, menuItem{Text: "Stats", Link: "/"}) return ret } func (wm *generalWebModule) GetBottomMenuEntries() []menuItem { var ret []menuItem return ret } func (wm *generalWebModule) handleStats(w http.ResponseWriter, req *http.Request) { initRequest(w, req) type ChannelStat struct { Name string MemberCount int MessageCount int } type StatData struct { TotalChannelMessages int TotalChannels int ChannelStats []ChannelStat Error string } // Get the global stats var s StatData var err error openDatabase() chanlst := getChannelList() var chanstats []ChannelStat for _, k := range chanlst { chanstats = append(chanstats, ChannelStat{ Name: getChannelName(k), MemberCount: getChannelMemberCount(k), MessageCount: getChannelMessageCount(k), }) } s.ChannelStats = chanstats s.TotalChannelMessages = getTotalChannelMsgCount() s.TotalChannels = len(chanlst) closeDatabase() sc := "var stats = {totalchannelmessages:" sc = fmt.Sprintf("%s%d,", sc, s.TotalChannelMessages) sc = sc + "\"channels\":[" for _, k := range s.ChannelStats { sc = fmt.Sprintf("%s{name:\"%s\",member_count:%d,message_count:%d},", sc, k.Name, k.MemberCount, k.MessageCount, ) } // Trim the last , sc = sc[:len(sc)-1] sc = sc + "]" sc = sc + "};" addToInlineScript(sc) site.Scripts = append(site.Scripts, "/assets/js/main_stats.js") if err != nil { setFlashMessage("Error Counting Channel Messages", "error") } site.TemplateData = s setMenuItemActive("Stats") showPage("stats.html", site, w) }